<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Portland JavaScript Admirers</title>
 <link href="http://pdxjs.com/atom.xml" rel="self"/>
 <link href="http://pdxjs.com/"/>
 <updated>2013-05-22T16:08:19-07:00</updated>
 <id>http://pdxjs.com/</id>
 <author>
   <name>Portland JavaScript Admirers contributers</name>
   <email>pdxjs@googlegroups.com</email>
 </author>

 
 <entry>
   <title>PDXjs February 2012 Meeting Recap</title>
   <link href="http://pdxjs.com/2012/02/23/pdxjs-february-meeting-recap.html"/>
   <updated>2012-02-23T00:00:00-08:00</updated>
   <id>http://pdxjs.com/2012/02/23/pdxjs-february-meeting-recap</id>
   <content type="html">&lt;p&gt;At our February meeting, we went over some ideas for improving the PDXjs website, Howard Leis Ship gave a talk on CoffeeScript, the upcoming CouchConf Portland, 7 Databases in 7 weeks, promise libraries, EventReactor, and analysis of the recently popular &lt;a href='https://www.destroyallsoftware.com/talks/wat'&gt;Wat&lt;/a&gt; video.&lt;/p&gt;

&lt;h3 id='pdxjscom_wishlist'&gt;PDXjs.com wishlist&lt;/h3&gt;

&lt;p&gt;A wishlist of possible updates to this site:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;live editing for real-time meeting notes&lt;/li&gt;

&lt;li&gt;meeting times (currently presented via Calagator widget, that may need some fixing up)&lt;/li&gt;

&lt;li&gt;tomorrow&amp;#8217;s winning lottery numbers&lt;/li&gt;

&lt;li&gt;EtherPad Lite, implemented with node.js, could be used for meeting notes&lt;/li&gt;

&lt;li&gt;notes from meetings&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='coffeescript'&gt;CoffeeScript&lt;/h3&gt;

&lt;p&gt;Howard Lewis Ship gave a talk on CoffeeScript&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;try-finally is broken in IE7&lt;/li&gt;

&lt;li&gt;how does one debug CoffeeScript apps?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='couchconf_pdx'&gt;CouchConf PDX&lt;/h3&gt;

&lt;p&gt;&lt;a href='http://www.couchbase.com/couchconf-portland'&gt;CouchConf Portland&lt;/a&gt; is coming up on March 14, 2012.&lt;/p&gt;

&lt;h3 id='7_databases_in_7_weeks'&gt;7 Databases in 7 Weeks&lt;/h3&gt;

&lt;p&gt;The upcoming book, &lt;a href='http://pragprog.com/book/rwdata/seven-databases-in-seven-weeks'&gt;7 Databases in 7 weeks&lt;/a&gt; was mentioned as a good introduction to various NoSQL databases and the reasons for choosing one over another.&lt;/p&gt;

&lt;h3 id='promises_promises'&gt;Promises, Promises&lt;/h3&gt;

&lt;p&gt;What is the best promise library for Node.js?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://coolaj86.info/futures/'&gt;futures.js&lt;/a&gt; was recommended&lt;/li&gt;

&lt;li&gt;&lt;a href='https://github.com/kriskowal/q'&gt;q&lt;/a&gt; is another option, with addons in &lt;a href='https://github.com/kriskowal/qq'&gt;qq&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='https://github.com/caolan/async'&gt;async&lt;/a&gt; is another&lt;/li&gt;

&lt;li&gt;&lt;a href='http://alogicalparadox.com/oath/'&gt;oath&lt;/a&gt; is yet another&lt;/li&gt;

&lt;li&gt;&lt;a href='https://github.com/observing/eventreactor'&gt;EventReactor&lt;/a&gt; is another nice tool for working with async code in node and in the browser&lt;/li&gt;

&lt;li&gt;stay tuned for a talk on promises at a future PDX.js meeting&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='wat'&gt;Wat&lt;/h3&gt;

&lt;p&gt;Ryan Munro explained the JS segment from the &lt;a href='https://www.destroyallsoftware.com/talks/wat'&gt;Wat&lt;/a&gt; - the destroy all software video.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;{} represents an empty block syntax&lt;/li&gt;

&lt;li&gt;Ryan demoed a trick for strengthening the js type system, setting the valueOf function for various JavaScript built-in types to undefined&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other Weirdness&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;~ is bitwise &amp;#8220;not&amp;#8221;. -~n can be used to increment a number n that may be undefined&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='from_after_the_meeting'&gt;From after the meeting:&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://walmartlabs.github.com/thorax/'&gt;Thorax&lt;/a&gt; is a framework on top of Backbone&lt;/li&gt;

&lt;li&gt;&lt;a href='https://github.com/dannycoates/node-inspector'&gt;Node-Inspector&lt;/a&gt; could be really handy for debugging node.js apps.&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Cappuccino</title>
   <link href="http://pdxjs.com/2009/11/08/cappuccino.html"/>
   <updated>2009-11-08T00:00:00-08:00</updated>
   <id>http://pdxjs.com/2009/11/08/cappuccino</id>
   <content type="html">&lt;p&gt;This month we had a great detailed talk on &lt;a href='http://cappuccino.org/'&gt;Cappuccino&lt;/a&gt;, given by Howard Lewis Ship. Cappuccino is a JavaScript framework for creating rich graphical interfaces in the browser. It is an effort by some former Apple engineers and is the flagship product of their company, &lt;a href='http://280north.com/'&gt;280 North&lt;/a&gt;. They essentially re-created OS X&amp;#8217;s &lt;a href='http://developer.apple.com/cocoa/'&gt;Cocoa&lt;/a&gt; library and adapted it to run on Objective-J, a dialect on top of JavaScript that is designed to be similar to Objective-C. The advantage of using Objective-J instead of pure JavaScript is that you can use the Cappuccino libraries with pretty much the same API that you would use when building native Cocoa apps. Real live Cappuccino apps that you can try out are &lt;a href='http://280slides.com/'&gt;280Slides&lt;/a&gt; by 280 North and &lt;a href='http://almost.at/'&gt;almost.at&lt;/a&gt;, which is an independent effort.&lt;/p&gt;

&lt;p&gt;One of the most impressive points that Howard brought up has to do with Cappuccino&amp;#8217;s interoperability with Apple&amp;#8217;s Xcode IDE. Xcode includes an Interface Builder tool which acts as a powerful WYSIWYG interface for building graphical interfaces. Interface Builder outputs an XML description of your design called a nib file. Cappuccino includes a tool that can automatically convert a nib file into its Cappuccino equivalent. So you can design your views in Interface Builder and run them in the web browser with Cappuccino in the same way you would expect from a native Cocoa app.&lt;/p&gt;

&lt;p&gt;So far Interface Builder is the only component of Xcode that Cappuccino integrates with. But the 280 North team is working on better IDE support in the form of &lt;a href='http://280atlas.com/'&gt;Atlas&lt;/a&gt;, their own IDE. Atlas is intended to be a cross-platform tool for building Cappuccino apps. It also happens to be written in Cappuccino. The web site hints that Atlas may include an option to create builds of Cappuccino-based web code that look and feel like desktop apps. It looks like 280 North is planning to use Atlas as their revenue stream since it will be a paid app. The Atlas Developer Beta Program will launch on November 15th.&lt;/p&gt;

&lt;p&gt;Cappuccino will be most comfortable to to programmers who have experience with Objective-C and with Cocoa - or &lt;a href='http://en.wikipedia.org/wiki/NeXTSTEP'&gt;NeXTSTEP&lt;/a&gt; which is what Cocoa is based on. Howard mentioned that Cappuccino&amp;#8217;s documentation can be unhelpful and incomplete. But because Cappuccino is modeled so closely after Cocoa you can generally use Cocoa reference materials instead, which are very complete. Similarly, developing Cappuccino apps will be easiest for Mac users with access to Xcode.&lt;/p&gt;

&lt;p&gt;Objective-C was created as a way to bring some of the powerful features of Smalltalk to C programming. In the same way that Objective-C is a layer on top of raw C code, Objective-J is a layer on top of JavaScript. To use Cappuccino&amp;#8217;s APIs your classes and methods will have to look like Objective-C code. But within your methods and in your support code you can use pure JavaScript. Objective-J compiles down to JavaScript when a Cappuccino app is compiled. Writing interfaces to Objective-J APIs from pure JavaScript takes a little work but is possible.&lt;/p&gt;

&lt;p&gt;Objective-J makes some deviations from Objective-C in addition to its JavaScript foundation. Objective-J has no header files: all of the declarations you need are put straight into code files. And though Objective-J requires you to declare types in your method signatures and instance variables, it does not actually perform any type checking. One pitfall when coming from Objective-C is to try to declare local variables with a specific type. In fact you are required to declare all local variables with JavaScript&amp;#8217;s native &lt;code&gt;var&lt;/code&gt; keyword. There is also no syntactic distinction for pointers in Objective-J because all non-primitive values are passed by reference in JavaScript.&lt;/p&gt;

&lt;p&gt;The advantage of Cappuccino is that you can use it to build very powerful, cross-browser, graphical interfaces quite easily. And you get the advantages of existing tools, like Xcode&amp;#8217;s Interface Builder plus proven technologies of Cocoa and NeXTSTEP. If you have experience with those technologies you have a shot at a very smooth transition to building web applications. And unlike Cocoa, Cappuccino is completely &lt;a href='http://github.com/280north/cappuccino'&gt;open source&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The downsides are that Cappuccino&amp;#8217;s documentation is not great, as is mentioned above. Debugging can be painful because the compiler errors that you see will often provide no information as to what the problem is - though Howard recommends using Safari for the least painful debugging experience possible. Because of its Mac roots Cappuccino development tends to be Mac-centric - at least until Atlas is released. Compiled Objective-J code does not appear to be optimized for performance; so Cappuccino apps might not perform quite as well as apps built on other frameworks. And there are some aspects of web programming that do not come up as much in desktop applications - in particular background server communication. Cocoa does not have much support for stuff like that, so you will have to use other tools or build your own solution.&lt;/p&gt;

&lt;p&gt;The slides from this talk are online on &lt;a href='http://tapestryjava.blogspot.com/2009/10/brew-up-rich-web-application-with.html'&gt;Howard&amp;#8217;s blog&lt;/a&gt;. Howard&amp;#8217;s demo code is also online on &lt;a href='http://github.com/hlship/nfjs-cappuccino'&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have questions about Cappuccino feel free to post comments here or to send questions to our &lt;a href='http://groups.google.com/group/pdxjs'&gt;mailing list&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Sammy and Cross-Origin Resource Sharing</title>
   <link href="http://pdxjs.com/2009/08/02/sammy-and-cross-origin-resource-sharing.html"/>
   <updated>2009-08-02T00:00:00-07:00</updated>
   <id>http://pdxjs.com/2009/08/02/sammy-and-cross-origin-resource-sharing</id>
   <content type="html">&lt;h3 id='sammy'&gt;Sammy&lt;/h3&gt;

&lt;p&gt;At our July meeting Scott Becker gave us a presentation on a wonderful tool called &lt;a href='http://code.quirkey.com/sammy/'&gt;Sammy&lt;/a&gt;. Sammy is a framework inspired by the Ruby framework, &lt;a href='http://www.sinatrarb.com/'&gt;Sinatra&lt;/a&gt;, for structuring web applications on the client side. It works on the idea that a rich application can have many different virtual pages in a single browser page. Sammy maps each virtual page to a URL using the fragment portion of the URL do distinguish between different virtual pages in the browser page. For example, &lt;code&gt;example.com/app/#/main&lt;/code&gt; and &lt;code&gt;example.com/app/#/subpage&lt;/code&gt; could represent two different virtual pages, or &amp;#8216;actions&amp;#8217;.&lt;/p&gt;

&lt;p&gt;To use Sammy, you register a series of routes with a callback attached to each route. Routes can be literal strings, regular expressions, or paths with named parameters. Whenever the browser address changes Sammy automatically scans through the list of routes looking for the first one that matches the new page address. When it finds the match Sammy runs the associated callback.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;app&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;sammy&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='kd'&gt;with&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;

    &lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;#/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='kd'&gt;with&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;#main&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;text&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Welcome!&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;}});&lt;/span&gt;

    &lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;#/say-my-name/:name&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='kd'&gt;with&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;#main&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;text&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Hello, &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;params&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]);&lt;/span&gt;
    &lt;span class='p'&gt;}});&lt;/span&gt;

    &lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;#/pastries/votes&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='kd'&gt;with&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
	&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;#main&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;text&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Please vote for the pastry you want at the next meeting.&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;}});&lt;/span&gt;

&lt;span class='p'&gt;}});&lt;/span&gt;

&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;document&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;ready&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;app&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;run&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;#/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Mapping URL fragments to different areas of the application means that your users can create bookmarks that go directly to those areas. It also means that the browser back and forward buttons will work as expected even when everything is technically running in a single page.&lt;/p&gt;

&lt;p&gt;Sammy can intercept form posts, allowing your application to easily the data submitted without actually sending it to the server. When checking for a route match, Sammy checks the form&amp;#8217;s submit method against the method used to register each route.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;app&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;sammy&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='kd'&gt;with&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;

    &lt;span class='p'&gt;...&lt;/span&gt;

    &lt;span class='nx'&gt;post&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;#/pastries/votes&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='kd'&gt;with&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;params&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;pastry_type&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Glazed Donuts&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
            &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;#main&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;text&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Excellent choice!&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
        &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
            &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;#main&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;text&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Well, we\&amp;#39;ll see.&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
        &lt;span class='p'&gt;}&lt;/span&gt;
        &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;
    &lt;span class='p'&gt;}});&lt;/span&gt;

&lt;span class='p'&gt;}});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sammy even includes support for a templating system. Templates are hosted on the server as separate files. After a template is loaded once it is cached in the browser so that subsequent renderings of the same template will not produce more than one HTTP request.&lt;/p&gt;

&lt;p&gt;Here is an example of templating in action from Scott&amp;#8217;s slides:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;app&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;sammy&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='kd'&gt;with&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;element_selector&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;#main&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

    &lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;#/tasks/:id&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='kd'&gt;with&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;task&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;db&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;collection&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;tasks&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;params&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]).&lt;/span&gt;&lt;span class='nx'&gt;json&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
        &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;partial&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;/templates/task_details.html.erb&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;}});&lt;/span&gt;

&lt;span class='p'&gt;}});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here is what the corresponding template looks like:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='html+erb'&gt;&lt;span class='nt'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='na'&gt;id=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;task_&lt;/span&gt;&lt;span class='cp'&gt;&amp;lt;%=&lt;/span&gt; &lt;span class='n'&gt;task&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;__id__&lt;/span&gt; &lt;span class='cp'&gt;%&amp;gt;&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
  &lt;span class='nt'&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;&lt;span class='cp'&gt;&amp;lt;%=&lt;/span&gt; &lt;span class='n'&gt;task&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;entry&lt;/span&gt; &lt;span class='cp'&gt;%&amp;gt;&lt;/span&gt;&lt;span class='nt'&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, templates can come in &lt;a href='http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/'&gt;ERB&lt;/a&gt; format where dynamic data is injected on the client side when the template is rendered. Usually ERB embeds Ruby code in a template. But in Sammy&amp;#8217;s case it embeds JavaScript code instead. Templates can also be plain HTML if you prefer.&lt;/p&gt;

&lt;p&gt;The slides from Scott&amp;#8217;s talk are online on &lt;a href='http://synthesis.sbecker.net/articles/2009/07/22/all-about-sammy'&gt;Scott&amp;#8217;s blog&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id='crossorigin_resource_sharing'&gt;Cross-Origin Resource Sharing&lt;/h3&gt;

&lt;p&gt;Jesse Hallett talked about Cross-Origin Resource Sharing. This is the term for an emerging standard for making cross-site Ajax requests natively, without the need for a proxy.&lt;/p&gt;

&lt;p&gt;The recent crop of browsers allow cross-site XMLHttpRequests under certain conditions. Previous implementations of XMLHttpRequest did not allow cross-site requests to reduce the risks associated with &lt;a href='http://en.wikipedia.org/wiki/Cross-site_request_forgery'&gt;cross-site request forgery&lt;/a&gt; and &lt;a href='http://en.wikipedia.org/wiki/Cross-site_scripting'&gt;cross-site scripting&lt;/a&gt; attacks. In order to allow cross-site XHR without making web servers vulnerable to cross-site attacks, the &lt;a href='http://dev.w3.org/2006/waf/access-control/'&gt;W3C Access Control specification&lt;/a&gt; defines a protocol for web servers to speciffy cross-origin security policies.&lt;/p&gt;

&lt;p&gt;When the browser sends a basic cross-site XHR request, it includes an &lt;code&gt;Origin&lt;/code&gt; header specifying the host, port, and protocol that the request originated from. A compliant server will include an &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt; header in the HTTP response. The content of the response header may be a wildcard, &lt;code&gt;*&lt;/code&gt;, if the server accepts requests from any origin for that URL and request method. Or the header may give a whitelist of origins that are specifically allowed. Upon receiving the response the browser checks the &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt; header and if the origin of the request does not match the server&amp;#8217;s policy, then the browser blocks the response.&lt;/p&gt;

&lt;p&gt;This simple exchange is used for GET requests and POST requests with content types of application/x-www-form-urlencoded, multipart/form-data, and text/plain. It is also required that requests not include any custom HTTP headers. Those are any headers that start with &amp;#8216;X-&amp;#8216;. For XHR requests that do not meet these criteria a somewhat more complicated &amp;#8216;preflight&amp;#8217; request is made to determine if a cross-site request is allowed. The browser sends an OPTIONS request to the server specifying the request method, content-type, and custom headers that are about to be sent. The server responds with access control headers specifying which request methods, content types, and custom request headers are allowed. If the server&amp;#8217;s policy is compatible with the XHR request, then the browser sends the real request.&lt;/p&gt;

&lt;p&gt;If a web server is hosting content on a given URL that is reasonably safe to server cross-site, then the maintainers of the web server may choose a liberal access policy. On the other hand content on a URL that would be dangerous to serve cross-site, such as content that is protected by cookie authentication, would be better protected by denying cross-site requests.&lt;/p&gt;

&lt;p&gt;The Access Control protocol takes the approach of a conservative default. If the server does not include an &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt; header in its responses then the browser assumes that cross-site requests are not allowed.&lt;/p&gt;

&lt;p&gt;The latest release of jQuery does not support cross-site requests. Other libraries will probably have similar problems. But there is &lt;a href='http://gist.github.com/152418'&gt;an example online&lt;/a&gt; demonstrating how to perform a cross-site request through the native DOM API.&lt;/p&gt;

&lt;p&gt;There are thorough explanations of CORS from the &lt;a href='https://developer.mozilla.org/En/HTTP_Access_Control'&gt;Mozilla Developer Center&lt;/a&gt; and &lt;a href='http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/'&gt;hacks.mozilla.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Firefox 3.5, Safari 4, and Google Chrome 2 implement CORS. Internet Explorer 8 has partial support; but uses &lt;a href='http://msdn.microsoft.com/en-us/library/cc288060%28VS.85%29.aspx'&gt;a different API&lt;/a&gt; instead of extending XMLHttpRequest. It is unclear at this point when Opera will incorporate the standard.&lt;/p&gt;

&lt;p&gt;Hopefully someday all browsers will support CORS. In the meantime we need fallbacks for the browsers that don&amp;#8217;t. For that Jesse recommends &lt;a href='http://flxhr.flensed.com/'&gt;flXHR&lt;/a&gt;, which is a client-side proxy implemented in Flash. Instead of using a server-side proxy, requests made in the browser are directed to an invisible Flash movie. The Flash code makes the actual HTTP request and proxies the response back to your JavaScript code.&lt;/p&gt;

&lt;p&gt;There are several advantages to using flXHR over other methods for getting around the &lt;a href='http://en.wikipedia.org/wiki/Same_origin_policy'&gt;same origin policy&lt;/a&gt;. It is easier to run a client-side proxy than it is to maintain a server-side proxy on every domain you want to make cross-site requests from. Unlike &lt;a href='http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/'&gt;JSONP&lt;/a&gt; and &lt;a href='http://nb.io/hacks/csshttprequest'&gt;CSSHttpRequest&lt;/a&gt; which can only make GET requests, flXHR can make any type of request. Unline JSONP, flXHR does not require your application to blindly execute the response from another domain. And flXHR requires much less server-side setup than CSSHttpRequest does.&lt;/p&gt;

&lt;p&gt;For the sake of security Flash respects server-side access policies when making cross-site requests in much the same way that CORS works. So to use flXHR you will need to set up an access policy on any servers you want to make requests to. But instead of declaring policy in HTTP headers you will need to serve a special crossdomain.xml document.&lt;/p&gt;

&lt;p&gt;There are flXHR plugins available for several JavaScript frameworks - including &lt;a href='http://flxhr.flensed.com/jquery.php'&gt;one for jQuery&lt;/a&gt;. The plugin makes use of another jQuery plugin called &lt;a href='http://plugins.jquery.com/project/XHR'&gt;XHR&lt;/a&gt; which provides a registry for pluggable backends for HTTP requests. To make requests through flXHR you will need to pass a &lt;code&gt;transport&lt;/code&gt; parameter to jQuery&amp;#8217;s ajax methods.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='nx'&gt;jQuery&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;ajax&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
    &lt;span class='nx'&gt;url&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;...&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;transport&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;flXHRproxy&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='c1'&gt;// ...&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Someday soon it would be nice to see a plugin that will transparently make requests using CORS on browsers with the necessary support, and that will fall back to flXHR or something similar in other browsers.&lt;/p&gt;

&lt;h3 id='serverside_javascript_and_graphics'&gt;Server-Side JavaScript and Graphics&lt;/h3&gt;

&lt;p&gt;We spent some time talking about server-side JavaScript for implementing web applications. It would be really great if somebody could give a talk on this subject at an upcoming meeting. But what we know so far is that the new kind on the block is &lt;a href='http://www.joyent.com/products/joyent-smart-platform/'&gt;Joyent&amp;#8217;s Smart Platform&lt;/a&gt;. In addition to running JavaScript the smart platform automatically handles scaling and provisioning. And the platform is &lt;a href='http://github.com/joyent'&gt;open source&lt;/a&gt;; so you can run it on your own machines.&lt;/p&gt;

&lt;p&gt;There is a standardization going on to make server-side JavaScript code as interoperable as possible. The project behind that is called &lt;a href='https://wiki.mozilla.org/ServerJS'&gt;ServerJS&lt;/a&gt;. There seem to be several implementations in the works already.&lt;/p&gt;

&lt;p&gt;Mike Leach brought up another server-side framework called &lt;a href='http://ejohn.org/blog/server-side-javascript-with-jaxer/'&gt;Jaxer&lt;/a&gt; that allows you to mix server and client logic in a single code base.&lt;/p&gt;

&lt;p&gt;We also had a discussion of the tools out there for rendering charts and graphics. Some of the names mentioned were &lt;a href='http://raphaeljs.com/'&gt;RaphaelJS&lt;/a&gt; and &lt;a href='http://processingjs.org/'&gt;ProcessingJS&lt;/a&gt; for graphics; and &lt;a href='http://bluff.jcoglan.com/'&gt;Bluff&lt;/a&gt; and &lt;a href='http://code.google.com/p/flot/'&gt;Flot&lt;/a&gt; for graphs and plots.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>PDXjs June Meeting Recap - Agile JavaScript Testing</title>
   <link href="http://pdxjs.com/2009/07/09/pdxjs-june-meeting-recap-agile-javascript-testing.html"/>
   <updated>2009-07-09T00:00:00-07:00</updated>
   <id>http://pdxjs.com/2009/07/09/pdxjs-june-meeting-recap-agile-javascript-testing</id>
   <content type="html">&lt;p&gt;Our June meeting was the first meeting at &lt;a href='http://www.kongregate.com/'&gt;Kongregate&lt;/a&gt;. This meeting was more free-form than most. But Scott Becker talked more about behavior-driven development in JavaScript. He brought up a lot of tools that he hadn&amp;#8217;t covered in his previous talk.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.slideshare.net/joydivider/agile-javascript-testing'&gt;Slides from Scott&amp;#8217;s talk&lt;/a&gt; are online. Scott also drew up this list of links to various tools that are useful for testing JavaScript.&lt;/p&gt;

&lt;h3 id='stuff_mentioned_in_presentation'&gt;Stuff Mentioned in Presentation&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href='http://github.com/nkallen/screw-unit/tree/master'&gt;Screw.Unit&lt;/a&gt; - BDD framework for JS, RSpec-like&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://github.com/andykent/smoke/tree/master'&gt;Smoke&lt;/a&gt; - mocking and stubbing framework, RSpec-like&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://github.com/relevance/blue-ridge/tree/master'&gt;Blue Ridge&lt;/a&gt; - Rails plugin - tie in JS tests with the rest of your rails tests. Bundles Screw.Unit, Smoke, and env.js.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://www.mozilla.org/rhino/'&gt;Rhino&lt;/a&gt; - JavaScript interpreter written in Java&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://ejohn.org/blog/bringing-the-browser-to-the-server/'&gt;env.js&lt;/a&gt; - JavaScript-based DOM implementation. Useful for automating tests.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://code.google.com/p/js-test-driver/'&gt;js-test-driver&lt;/a&gt; - parallel cross-browser JS test server&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='further_possible_exploration_for_js__browser_level_testing'&gt;Further possible exploration for JS / Browser level testing&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href='http://visionmedia.github.com/jspec/'&gt;JSpec&lt;/a&gt; - another BDD framework like Screw.Unit, with cleaner syntax&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://github.com/gisikw/jsocka/tree/master'&gt;JSocka&lt;/a&gt; - mocking and stubbing, mocha-like&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://seleniumhq.org/'&gt;Selenium&lt;/a&gt; - browser-driven automated testing; complaints about brittleness of tests&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://www.getwindmill.com/'&gt;Windmill&lt;/a&gt; - browser-driven automated testing&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://wtr.rubyforge.org/'&gt;Watir&lt;/a&gt; - browser-driven automated testing&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://tenderlovemaking.com/2009/04/05/testing-javascript-outside-the-browser/'&gt;Johnson&lt;/a&gt; - Headless browser, uses ruby to load your html and execute your javascript. But I&amp;#8217;m not sure how flexible / full featured this is.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://celerity.rubyforge.org/'&gt;Celerity&lt;/a&gt; - JRuby interface to HtmlUnit, a Java-based headless browser with JavaScript support&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://github.com/langalex/culerity/tree/master'&gt;Culerity&lt;/a&gt; - A bridge between Cucumber and Celerity. Basically re-implementing the webrat helpers to drive Celerity.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://groups.google.com/group/webrat/browse_thread/thread/1db11de39945e3a7
'&gt;Webrat&lt;/a&gt; - Selenium driver&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://fireunit.org/'&gt;FireUnit&lt;/a&gt; - JavaScript Unit Testing Extension for Firebug&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://testswarm.com/'&gt;TestSwarm&lt;/a&gt; - Distributed Continuous Integration for JavaScript&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>PDXjs May Meeting Recap</title>
   <link href="http://pdxjs.com/2009/07/08/pdxjs-may-meeting-recap.html"/>
   <updated>2009-07-08T00:00:00-07:00</updated>
   <id>http://pdxjs.com/2009/07/08/pdxjs-may-meeting-recap</id>
   <content type="html">&lt;p&gt;At our May meeting the air was abuzz with preparations for &lt;a href='http://opensourcebridge.org/'&gt;Open Source Bridge&lt;/a&gt;. Scott Becker was preparing a topic on behavior-driven development in JavaScript with a focus on using &lt;a href='http://github.com/nkallen/screw-unit'&gt;Screw.Unit&lt;/a&gt;. Screw.Unit is a spec framework based on Ruby&amp;#8217;s &lt;a href='http://rspec.info/'&gt;RSpec&lt;/a&gt;. Scott gave a preview of that talk for the JavaScript Admirers.&lt;/p&gt;
&lt;object height='360' width='640'&gt;&lt;param name='allowfullscreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;param name='movie' value='http://vimeo.com/moogaloop.swf?clip_id=5497127&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' /&gt;&lt;embed src='http://vimeo.com/moogaloop.swf?clip_id=5497127&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' allowfullscreen='true' type='application/x-shockwave-flash' allowscriptaccess='always' height='360' width='640' /&gt;&lt;/object&gt;
&lt;p&gt;&lt;a href='http://opensourcebridge.org/2009/wiki/Agile_JavaScript_Testing'&gt;Notes from Scott&amp;#8217;s talk at OSBridge&lt;/a&gt; are online on the OSBridge website.&lt;/p&gt;

&lt;p&gt;I was also working on my own OSBridge talk on cluster analysis. Cluster analysis is a statistical analysis technique that is used to find patterns in a data set based on known similarities of elements in that set.&lt;/p&gt;
&lt;object height='360' width='640'&gt;&lt;param name='allowfullscreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;param name='movie' value='http://vimeo.com/moogaloop.swf?clip_id=5504047&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' /&gt;&lt;embed src='http://vimeo.com/moogaloop.swf?clip_id=5504047&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' allowfullscreen='true' type='application/x-shockwave-flash' allowscriptaccess='always' height='360' width='640' /&gt;&lt;/object&gt;
&lt;p&gt;&lt;a href='http://github.com/hallettj/cluster.js'&gt;Code from my presentation&lt;/a&gt; and &lt;a href='http://docs.google.com/Presentation?id=ah89wzc8d66j_17dchh4xf4'&gt;slides from my talk at OSBridge&lt;/a&gt; are available online.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>PDXjs April Meeting Recap</title>
   <link href="http://pdxjs.com/2009/05/06/pdxjs-april-meeting-recap.html"/>
   <updated>2009-05-06T00:00:00-07:00</updated>
   <id>http://pdxjs.com/2009/05/06/pdxjs-april-meeting-recap</id>
   <content type="html">&lt;p&gt;This month we heard talks about several new JavaScript features and techniques. Duncan Beevers started off with a talk titled JavaScript Packaging Strategies. He recommends using &lt;a href='http://getsprockets.org/'&gt;Sprockets&lt;/a&gt; to combine JavaScript files with smart dependency handling. And he says that &lt;a href='http://developer.yahoo.com/yui/compressor/'&gt;YUI Compressor&lt;/a&gt; is a good way to reduce the file size of the resulting package. Though for best results you will want to combine YUI Compressor with &lt;a href='http://betterexplained.com/articles/how-to-optimize-your-site-with-gzip-compression/'&gt;gzip&lt;/a&gt;.&lt;/p&gt;
&lt;object height='360' width='640'&gt;&lt;param name='allowfullscreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;param name='movie' value='http://vimeo.com/moogaloop.swf?clip_id=4518486&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' /&gt;&lt;embed src='http://vimeo.com/moogaloop.swf?clip_id=4518486&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' allowfullscreen='true' type='application/x-shockwave-flash' allowscriptaccess='always' height='360' width='640' /&gt;&lt;/object&gt;
&lt;p&gt;The slides from Duncan&amp;#8217;s talk are available at &lt;a href='http://docs.google.com/Presentation?id=d9nrbm4_80kvp92m5b'&gt;http://docs.google.com/Presentation?id=d9nrbm4_80kvp92m5b&lt;/a&gt; and the code from his demo is available at &lt;a href='http://github.com/duncanbeevers/packaging_javascript_demo/'&gt;http://github.com/duncanbeevers/packaging_javascript_demo/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Duncan has &lt;a href='http://github.com/duncanbeevers/sprockets/'&gt;a fork of Sprockets&lt;/a&gt; and &lt;a href='http://github.com/duncanbeevers/asset_packager/'&gt;a Rails plugin for packaging JavaScript files&lt;/a&gt; on Github.&lt;/p&gt;

&lt;p&gt;Next up, Paul Point Pen demonstrated the many features of &lt;a href='http://www.w3schools.com/tags/html5_video.asp'&gt;video&lt;/a&gt; and &lt;a href='http://www.w3schools.com/tags/html5_audio.asp'&gt;audio&lt;/a&gt; elements in &lt;a href='http://en.wikipedia.org/wiki/HTML_5'&gt;HTML 5&lt;/a&gt;. The native JavaScript API for these elements allows for tremendous control over playback and playback events. For example, you can execute a callback function whenever the user moves the video progress slider. It is also possible to feed video into a &lt;a href='https://developer.mozilla.org/en/Canvas_tutorial'&gt;canvas&lt;/a&gt; and manipulate the results pixel-by-pixel in real time for effects like &lt;a href='http://blog.mozbox.org/post/2009/04/12/Firefox-35:-a-new-experiment-with-Canvas-Video'&gt;live green-screening&lt;/a&gt; &lt;a href='https://developer.mozilla.org/samples/video/chroma-key/index.xhtml'&gt;in a browser&lt;/a&gt;.&lt;/p&gt;
&lt;object height='360' width='640'&gt;&lt;param name='allowfullscreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;param name='movie' value='http://vimeo.com/moogaloop.swf?clip_id=4439283&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' /&gt;&lt;embed src='http://vimeo.com/moogaloop.swf?clip_id=4439283&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' allowfullscreen='true' type='application/x-shockwave-flash' allowscriptaccess='always' height='360' width='640' /&gt;&lt;/object&gt;
&lt;p&gt;The slides from Paul&amp;#8217;s talk are available online at &lt;a href='http://html5.waytoocrowded.com/'&gt;http://html5.waytoocrowded.com/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Video elements also integrate well with CSS 3 transforms, as you can see in this &lt;a href='http://people.mozilla.com/~prouget/demos/round/index.xhtml'&gt;demo of a circular video element&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;HTML 5 is still a work in progress. So browser support for video and audio elements is pretty inconsistent at this point. For example, different browsers do not support all of the same video and audio codects.&lt;/p&gt;

&lt;p&gt;Unfortunately the batteries in our camera died part-way through Paul&amp;#8217;s talk. So we do not have the very end recorded. I am sorry about that Paul. We will try to do better next time.&lt;/p&gt;

&lt;p&gt;Leif Warner demonstrated &lt;a href='https://developer.mozilla.org/en/e4x'&gt;E4X&lt;/a&gt;, which is a nifty new feature in &lt;a href='https://developer.mozilla.org/en/New_in_JavaScript_1.6'&gt;JavaScript 1.6&lt;/a&gt;. XML elements can now be expressed as primitives in JavaScript, giving them the same status as strings and arrays. E4X also provides some very handy methods for navigating XML data structures using JavaScript syntax.&lt;/p&gt;
&lt;object height='360' width='640'&gt;&lt;param name='allowfullscreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;param name='movie' value='http://vimeo.com/moogaloop.swf?clip_id=4406971&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' /&gt;&lt;embed src='http://vimeo.com/moogaloop.swf?clip_id=4406971&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' allowfullscreen='true' type='application/x-shockwave-flash' allowscriptaccess='always' height='360' width='640' /&gt;&lt;/object&gt;
&lt;p&gt;Most E4X implementations do not have a way to inject XML objects into the DOM, or to access DOM elements as E4X objects. So to interact with a web page using E4X you need to read in DOM elements as strings and convert them to E4X objects using the XML constructor:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;domEl  = document.getElementById(&amp;#39;main&amp;#39;);
e4xObj = new XML(domEl.innerHTML);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And convert XML structures into strings before inserting them into the DOM:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;domEl.innerHTML = e4xObj.toString();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, I talked about one of my favorite JavaScript libraries, &lt;a href='http://osteele.com/sources/javascript/functional/'&gt;Functional JavaScript&lt;/a&gt;. JavaScript has all of the necessary features to make it a good language for functional programming - the most important feature being &lt;a href='http://en.wikipedia.org/wiki/First_Class_Functions'&gt;first-class functions&lt;/a&gt;. Functional JavaScript provides all of the functions you need to actually write functional programs comfortably. A lot of functions are included, but some of the highlights are &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt;, &lt;code&gt;curry&lt;/code&gt;, and &lt;code&gt;uncurry&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another feature that is included is the string lambda. Writing anonymous lambdas in JavaScript can get kind of ugly due to the verbosity of writing &lt;code&gt;function(x,y) { return ...; }&lt;/code&gt; over and over again. String lambdas are meant to address this issue by creating a mini syntax just for writing small functions. You can write an adding function like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;#39;x+y&amp;#39;.lambda();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can get even more terse by leaving out arguments. The &lt;code&gt;lambda&lt;/code&gt; method will assume that operators left out of a binary expression should be filled in with variables. So an add-one function could look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;#39;+1&amp;#39;.lambda();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you want to do something trickier, you can always explicitly declare the arguments of the function. For example, here is how you could write a string lambda that accepts arguments in a different order than the order in which they appear in the function body:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;#39;x,y -&amp;gt; y / x&amp;#39;.lambda();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All of the functions in Functional JavaScript implicitly call the &lt;code&gt;lambda&lt;/code&gt; method on any arguments that are expected to be functions. So most of the time you can express functions as bare strings:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;map(&amp;#39;*2&amp;#39;, [1,2,3,4]);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Check out the &lt;a href='http://osteele.com/sources/javascript/functional/'&gt;Functional JavaScript documentation&lt;/a&gt; for more about what string lambdas can do.&lt;/p&gt;

&lt;p&gt;I have &lt;a href='http://github.com/hallettj/functional-javascript/'&gt;a fork of Functional JavaScript&lt;/a&gt; on Github with compatibility fixes for running in a standalone interpreter, such as the Spidermonkey shell. Here is how you can get Functional JavaScript going in a standalone shell:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ js
js&amp;gt; load(&amp;#39;to-function.js&amp;#39;);
js&amp;gt; load(&amp;#39;functional.js&amp;#39;);
js&amp;gt; Functional.install();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I would like to thank Scott Becker for providing a video camera for us to use. It is a very nice camera, and I think the video quality came out great. Thanks to Scott all of the videos from this meeting are available in 720p HD.&lt;/p&gt;

&lt;p&gt;I look forward to seeing everybody again at the &lt;a href='http://calagator.org/events/1250457163'&gt;May meeting&lt;/a&gt;!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>PDXjs March Meeting Recap</title>
   <link href="http://pdxjs.com/2009/03/27/pdxjs-march-meeting-recap.html"/>
   <updated>2009-03-27T00:00:00-07:00</updated>
   <id>http://pdxjs.com/2009/03/27/pdxjs-march-meeting-recap</id>
   <content type="html">&lt;p&gt;We started of the March meeting of the Portland JavaScript Admirers with a demonstration of &lt;a href='http://reversehttp.net/'&gt;ReverseHttp&lt;/a&gt;. This is a protocol that allows any HTTP client to act as an HTTP server by receiving requests on a public-facing subdomain. So it allows for &lt;a href='http://www.reversehttp.net/demos/demo.html'&gt;a web server written in JavaScript to run in a normal web page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A useful application of a web server in a page is that provides a flexible way to push data into a client side application. The client does not have to be specially set up for polling; and the program pushing the data does not have to be specially configured to support &lt;a href='http://en.wikipedia.org/wiki/Long_polling#Long_polling'&gt;long-polling connections&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;ReverseHttp works through a gateway server. The client code, referred to in a ReverseHttp documentation as the &amp;#8216;application&amp;#8217;, requests some URL space from the server. The URL space can be a path with a unique root, so that multiple applications can register URL space on the same host, or the URL space can be a unique subdomain.&lt;/p&gt;

&lt;p&gt;The application next makes a long-polling request to the gateway server on a private URL. The server listens on the applications registered URL space and proxies an requests that come in to the application by embedding the request within the response to the application&amp;#8217;s long-polling request. The application composes a response which it sends back to the gateway server embedded in another HTTP request. The gateway server finally extracts the application&amp;#8217;s response and forwards it on to the original requestor.&lt;/p&gt;

&lt;p&gt;So long-polling is used internally by ReverseHttp. But ReverseHttp has advantages over other solutions that do not require a third-party gateway. It can be used in many different applications to send or receive different kinds of data without any modification to the gateway server. And the data source does not have to be specially outfitted to support long-pulling connections. So you can catch data from a source that was not originally designed to push data to a client-side application.&lt;/p&gt;

&lt;p&gt;I set up two demos to show off what ReverseHttp can do. One displays commit notifications from a Github repository in real time. The other is a chat application - a sort of a really stripped down reimplementation of Jabber. The demos are available at &lt;a href='http://pdxjs.com:8000/'&gt;http://pdxjs.com:8000/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next we heard about Windows Script Host from Rainier Anacker. This is a feature of Windows that allows users to write scripts to automate functions of the operating system. By default scripts can be written in JScript or VBScript - but there are addons that allow scripts to be written in other languages.&lt;/p&gt;

&lt;p&gt;When using JScript, operating system features are accessed through calls to the WScript.shell object. The API allows scripts to manipulate running programs, and to send keypresses and control sequences. For example, a script can open Notepad and enter &amp;#8220;Hello world&amp;#8221; into a new text file.&lt;/p&gt;

&lt;p&gt;Rainier demonstrated how Script Host can be used to grab all of the links from a web page and to display them with indexes in a new document. He mentioned that he has also used Script Host to manipulate Excel documents, thus saving a lot of manual work. It was brought up that Script Host is a good tool for automated testing when developing applications on Windows.&lt;/p&gt;

&lt;p&gt;For a good reference on how to use Script Host, see Windows 2000 Scripting Bible.&lt;/p&gt;

&lt;p&gt;After that we talked a little about ways to get around &lt;a href='http://en.wikipedia.org/wiki/Same_origin_policy'&gt;JavaScript&amp;#8217;s same-origin policy for HTTP requests&lt;/a&gt;. If you have control over the browsers that will be hosting your application, you can set up a direct socket to a server and expose an interface to that connection to the JavaScript interpreter. Otherwise your options are more limited. You can use workarounds like &lt;a href='http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/'&gt;JSONP&lt;/a&gt; and &lt;a href='http://nb.io/hacks/csshttprequest'&gt;HttpCssRequest&lt;/a&gt; - but those only allow GET requests and require server-side cooperation. You can use &lt;a href='http://developer.yahoo.com/javascript/howto-proxy.html'&gt;a server-side proxy&lt;/a&gt; to direct requests through. But you have to set up that proxy on your own domain.&lt;/p&gt;

&lt;p&gt;Hopefully though the troubles caused by the same origin policy are temporary. Firefox 3.1 - soon to be renumbered Firefox 3.5 - includes &lt;a href='https://developer.mozilla.org/En/HTTP_access_control'&gt;cross-domain XMLHttpRequest support&lt;/a&gt;. And Internet Explorer 8 also allows cross-domain requests via &lt;a href='http://msdn.microsoft.com/en-us/library/cc288060%28VS.85%29.aspx'&gt;a new API object called XDomainRequest&lt;/a&gt;. The new features in both browsers require servers to include an &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt; HTTP header in certain responses to indicate that they accept cross-domain connections - as described in &lt;a href='http://dev.w3.org/2006/waf/access-control/'&gt;this W3C working draft&lt;/a&gt;. Hopefully similar features will appear in other browsers in the near future.&lt;/p&gt;

&lt;p&gt;Finally we spent some time talking about neat things that can be done with HTML 5 and newer versions of the DOM API. We looked at &lt;a href='http://www.chromeexperiments.com/'&gt;Chrome Experiments&lt;/a&gt;, which is a Google-sponsored repository of JavaScript demos that push the limits of what JavaScript can do. We also looked at &lt;a href='http://raphaeljs.com/'&gt;Raphaël&lt;/a&gt;, which Merlyn brought up as a cross-browser-compatible tool for rendering vector graphics. And we drooled a little over &lt;a href='http://helephant.com/2008/07/the-bleeding-edge-of-web-queryselector-and-queryselectorall/'&gt;querySelector and querySelectorAll&lt;/a&gt;. querySelector and querySelectorAll These are new methods that are being added to the DOM API. They add jQuery-like selectors to the native API. For example,&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;document.querySelectorAll(&amp;quot;#large:nth-child(even)&amp;quot;);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;querySelector and querySelectorAll are already included in Safari 4, Firefox 3.1/3.5, IE8, and Opera&amp;#8217;s Acid 3 build.&lt;/p&gt;

&lt;p&gt;All in all it was a fun meeting. I am already looking forward to the next one!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>A Wanderer @ CubeSpace</title>
   <link href="http://pdxjs.com/2009/02/25/a-wanderer-at-cubespace.html"/>
   <updated>2009-02-25T00:00:00-08:00</updated>
   <id>http://pdxjs.com/2009/02/25/a-wanderer-at-cubespace</id>
   <content type="html">&lt;p&gt;Portland JavaScript Admirers have convened for a second time. There&amp;#8217;s a mailing list, a web site, plus you can follow on Calagator. We meet at CubeSpace, Portland&amp;#8217;s geek HQS (for software &amp;#8211; not competing with Free Geek). Ad: Women&amp;#8217;s Networking Group meets in Roman on second Tuesdays. &lt;a href='http://controlroom.blogspot.com/2009/02/wanderer-cubespace.html'&gt;read more&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>PDXjs January Meeting Recap</title>
   <link href="http://pdxjs.com/2009/01/29/pdxjs-january-meeting-recap.html"/>
   <updated>2009-01-29T00:00:00-08:00</updated>
   <id>http://pdxjs.com/2009/01/29/pdxjs-january-meeting-recap</id>
   <content type="html">&lt;p&gt;The inaugural meeting of the Portland JavaScript Admirers was a big success. We started off the evening with a round of introductions.&lt;/p&gt;
&lt;object height='302' width='400'&gt;&lt;param name='allowfullscreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;param name='movie' value='http://vimeo.com/moogaloop.swf?clip_id=3170513&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' /&gt;&lt;embed src='http://vimeo.com/moogaloop.swf?clip_id=3170513&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' allowfullscreen='true' type='application/x-shockwave-flash' allowscriptaccess='always' height='302' width='400' /&gt;&lt;/object&gt;
&lt;p&gt;After that we listened to several talks on the fine language that is JavaScript. I pulled out my copy of JavaScript: The Good Parts by Douglas Crockford and went over some of the tips from the book on how to write great JavaScript code. I focused on how and why to avoid global variables - which can sneak up on your JavaScript code if you are not careful.&lt;/p&gt;

&lt;p&gt;For example, you may know that variable declaration in JavaScript is optional. But did you know that variables that are not declared become global?&lt;/p&gt;

&lt;p&gt;Another tricky case is the &lt;code&gt;this&lt;/code&gt; keyword, which is used in method definitions to access attributes of the object that the method is attached to. But &lt;code&gt;this&lt;/code&gt; is actually re-assigned every time the method is invoked. So if the method is invoked as a function instead of as a method, i.e.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var f = object.method; f();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;instead of&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;object.method();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;then &lt;code&gt;this&lt;/code&gt; is assigned to the global object for the execution of &lt;code&gt;f&lt;/code&gt;. So any attributes set on &lt;code&gt;this&lt;/code&gt; then become global variables, and any attributes read from &lt;code&gt;this&lt;/code&gt; are read from the global namespace instead of from &lt;code&gt;object&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The code examples that I am pointing at in the video are online at &lt;a href='http://gist.github.com/64478'&gt;http://gist.github.com/64478&lt;/a&gt;.&lt;/p&gt;
&lt;object height='302' width='400'&gt;&lt;param name='allowfullscreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;param name='movie' value='http://vimeo.com/moogaloop.swf?clip_id=3139648&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' /&gt;&lt;embed src='http://vimeo.com/moogaloop.swf?clip_id=3139648&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' allowfullscreen='true' type='application/x-shockwave-flash' allowscriptaccess='always' height='302' width='400' /&gt;&lt;/object&gt;
&lt;p&gt;Scott Becker told us all about the features of &lt;a href='http://www.sproutcore.com/&amp;quot;'&gt;SproutCore&lt;/a&gt;, which is an MVC framework for browser-side applications. Among other things, SproutCore allows you to set up models for your data, which can act as an intermediary to transfer data to and from a server, or that can store data locally using something like Google Gears. Changes made in the model data automatically update data in your views, and vice versa, through the use of Key-Value Coding. Instead of directly accessing attribute values, you use &lt;code&gt;object.get(key)&lt;/code&gt; and &lt;code&gt;object.set(key, value)&lt;/code&gt;. This allows SproutCore to do all kinds of magical stuff for you.&lt;/p&gt;

&lt;p&gt;Views in SproutCore are things like forms and form elements, buttons, file selectors, and content areas. Instead of using the browser&amp;#8217;s form elements and buttons, SproutCore renders these as images to achieve a very slick-looking interface that is consistent across all browsers.&lt;/p&gt;

&lt;p&gt;Using Key-Value Coding with views, you can do stuff like get input from your user via a form, and display a live preview of the content he enters that is updated in real time, with very little work on your part.&lt;/p&gt;

&lt;p&gt;Unfortunately the batteries in our camera died partway through Scott&amp;#8217;s talk. So there are a few minutes missing from the middle.&lt;/p&gt;

&lt;p&gt;The slides from Scott&amp;#8217;s talk are online at &lt;a href='http://www.slideshare.net/joydivider/sproutcore-a-next-gen-javascript-framework'&gt;http://www.slideshare.net/joydivider/sproutcore-a-next-gen-javascript-framework&lt;/a&gt;.&lt;/p&gt;
&lt;object height='302' width='400'&gt;&lt;param name='allowfullscreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;param name='movie' value='http://vimeo.com/moogaloop.swf?clip_id=3188440&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' /&gt;&lt;embed src='http://vimeo.com/moogaloop.swf?clip_id=3188440&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' allowfullscreen='true' type='application/x-shockwave-flash' allowscriptaccess='always' height='302' width='400' /&gt;&lt;/object&gt;
&lt;p&gt;I went over the new features in &lt;a href='http://docs.jquery.com/Release:jQuery_1.3'&gt;jQuery 1.3&lt;/a&gt;. Many speed improvements have been made in this release. For example, the selector engine is 49% faster. And HTML injection into the document is a blazing 6 times faster. The new, faster selector engine has been broken out into its own project called &lt;a href='http://sizzlejs.com/'&gt;Sizzle&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This release also includes a complete rewrite of the event system. In addition to the &lt;code&gt;bind&lt;/code&gt; method for binding event handlers, jQuery 1.3 supports the most excellent &lt;code&gt;live&lt;/code&gt; method. Using &lt;code&gt;live&lt;/code&gt;, your event handler will be bound to all elements on the page that match a given selector, and any elements that appear in the future that match the same selector.&lt;/p&gt;

&lt;p&gt;jQuery events are now a self-contained system layered on top of native events. And the whole thing is compliant with W3C protocols for event handling.&lt;/p&gt;

&lt;p&gt;I also gave an introduction to jQuery in general for those who are not familiar with it. And we had a lively group discussion on why people might prefer jQuery over alternative libraries, like Prototype.&lt;/p&gt;
&lt;object height='302' width='400'&gt;&lt;param name='allowfullscreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;param name='movie' value='http://vimeo.com/moogaloop.swf?clip_id=3197144&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' /&gt;&lt;embed src='http://vimeo.com/moogaloop.swf?clip_id=3197144&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' allowfullscreen='true' type='application/x-shockwave-flash' allowscriptaccess='always' height='302' width='400' /&gt;&lt;/object&gt;
&lt;p&gt;Finally, J. Chris Anderson graciously jumped in to give us an introduction to &lt;a href='http://couchdb.apache.org/'&gt;CouchDB&lt;/a&gt;, a document-oriented database. CouchDB stores all of its data as JSON. There is no schema, and there are no tables. Queries are performed using the MapReduce pattern and can be written as stored JavaScript procedures.&lt;/p&gt;

&lt;p&gt;Because it is schema-less, CouchDB is not a great choice when you need a lot of relational features, like joins. But in cases where you have been frustrated by SQL, CouchDB can be a great choice. It excels at serving up very large datasets with a high number of concurrent queries.&lt;/p&gt;

&lt;p&gt;J. Chris is a CouchDB developer, and is one of the authors of CouchDB: Rough Cuts Version. We will hopefully be seeing another talk from him on using CouchDB to create pure-JavaScript applications.&lt;/p&gt;
&lt;object height='302' width='400'&gt;&lt;param name='allowfullscreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;param name='movie' value='http://vimeo.com/moogaloop.swf?clip_id=3197436&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' /&gt;&lt;embed src='http://vimeo.com/moogaloop.swf?clip_id=3197436&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1' allowfullscreen='true' type='application/x-shockwave-flash' allowscriptaccess='always' height='302' width='400' /&gt;&lt;/object&gt;
&lt;p&gt;At the end of the evening we retired to the Green Dragon for drinks. (Video suppressed.)&lt;/p&gt;

&lt;p&gt;If you are having any trouble with audio syncing in the flash player, I suggest downloading the MP4s directly. Click on the title in any of the videos to go to its page on Vimeo. There you can find the file download link in the lower-right area.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Admiring Javascript</title>
   <link href="http://pdxjs.com/2009/01/28/admiring-javascript.html"/>
   <updated>2009-01-28T00:00:00-08:00</updated>
   <id>http://pdxjs.com/2009/01/28/admiring-javascript</id>
   <content type="html">&lt;p&gt;I&amp;#8217;m at the first Portland JavaScript Admirers, well attended, geeks cheering for CubeSpace. We&amp;#8217;ve got lots of independent contractors, including my Hewlett-Packard friend from Pythoneers (how I&amp;#8217;m logged in, wearing the fleece), whom I also invited to our Ruby meetings, first Tuesdays. &lt;a href='http://mybizmo.blogspot.com/2009/01/admiring-javascript.html'&gt;read more&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 
</feed>
