<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Jesse Cravens]]></title>
  <link href="http://echo 'jessecravens.com' >> source/CNAME/atom.xml&#8221; rel=&#8221;self&#8221;/>
  <link href="http://echo 'jessecravens.com' >> source/CNAME/&#8221;/>
  <updated>2016-07-09T20:00:37-05:00</updated>
  <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/</id>
  <author>
    <name><![CDATA[Jesse Cravens]]></name>
    <email><![CDATA[jesse.cravens@gmail.com]]></email>
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[In Software, High Velocity === Winning]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2016/07/09/in-software/&#8221;/>
    <updated>2016-07-09T18:41:00-05:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2016/07/09/in-software</id>
    <content type="html"><![CDATA[<p>This article is mirrored on <a href="https://medium.com/@EngineeringDen/in-software-high-velocity-winning-4253b6d9113f#.6c93ecytb">Medium</a>.</p>

<p>It’s late and I’m walking back from the athletic complex to my car with my son, I say, &lsquo;Nice job, buddy, you went hard,’ but my voice cracks …. I’m hoarse from yelling &#8216;Man up, get back, find your man, Now push it! Get your head up, see your teammates!’ as I attempt to teach a group of fourth graders how to both apply a full court press and break it … managed chaos at its best. I sit down in the front seat, and take a deep breath. Man, there is nothing like an evening of high velocity basketball after a long day of high velocity software. Only problem is tonight we lost, and I hate losing.</p>

<p><a href="https://www.linkedin.com/company/10853709"><img class="imgR200" alt="Den Home App" src="http://echo 'jessecravens.com' >> source/CNAME/images/den/den_logo.png&#8221;></a></p>

<p>At <a href="https://www.linkedin.com/company/10853709">Den</a>, like any other early stage startup, velocity is king. In that regard, we are much like most startups, we build business requirements fast and at the highest quality possible.</p>

<p>In this highly competitive field, we are here to win. If building quality software, fast, is winning, concepts like technical debt, communication bottlenecks, monolithic architectures, and analysis paralysis are losing. As I drive home, I reflect on the last four whirlwind months. So far, at Den, we have been winning, we’ve built an amazing team and tech stack and our business partners are super pleased and excited. And most importantly, we have done it really fast.</p>

<p>So, how have we come this far this fast in building a high quality, cross platform mobile application and scalable microservice architecture in under six months? You may be surprised, but I feel it has more to do with the softer side of the industry than it does with the technical (that’s a future article).</p>

<h2>1. We’ve Maintained a Strong Relationship between Business and Engineering</h2>

<p>It starts with a relationship between our business partners built on a foundation of trust and engagement. We don’t look at our relationship with business as master-servant, we see it as an equal partnership, and I see myself as a Product Owner with an engineering background. Each of our engineers are future users of our application and are therefore emotionally invested in its success.</p>

<p>Also, my ability as CTO to communicate clearly our technical hurdles, skill set challenges, gaps in requirements, etc. is paramount to our success. For me, it is important to communicate challenges without making excuses. Every engineering decision that is made sets off a series of consequences, both good and bad. These trades will always come with negative consequences, depending on one’s perspective. A great <a href="https://www.linkedin.com/in/sam-price-2a99643">Tech Fellow, Sam Price from USAA</a> once told me, “Every decision you make will be wrong.” The key is making quick yet sound decisions, living with the outcomes, and communicating the trades as best you can to maintain trust between you and business partners.</p>

<p>It is also important to help engineers with understanding that a quick, smart decision must be made. Agree to disagree, but commit to the task, and help all understand that the decision is not necessarily short-sighted, and there will always be some negative consequences, some unseen and some foreseen. At the end of the day, analysis paralysis is not an option.</p>

<h2>2. We’ve Understood and Balanced ‘Short term’ and ‘Long term’ Velocity</h2>

<p>In our discussions, we are constantly differentiating between ‘short term’ and ‘long term’ velocity. Often, in past experiences, naive business partners press for decisions entirely based on short term velocity. At Den, as we rapidly develop, and respond to dynamic business needs, we leverage our collective experience to make sound technical decisions that positively impact our long term velocity. In other words, we want to make sure that later phases are not a nightmare of correcting all of the technical debt accumulated getting to MVP. Later development then becomes slow and painful, engineers get frustrated with the mess, business gets frustrated with the speed. So, we constantly balance sound architectural decisions that will impact our long term velocity with short term velocity wins.</p>

<p>When discussing with our business partners, the language we use to describe those decisions matters. If we trade a 2 hour task for an 8 hour, but it saves us 40 hours down the road when we need to pivot, we have made both a sound business and technical decision.</p>

<p>One key challenge is having the experience to anticipate those pivot points and understand all the technical implications behind the pivots, and very few can go at this alone. Which brings me to building a team of leads that possess, or have the potential to possess, all of the mixture of hard and soft skills I am alluding to.</p>

<h2>3. We’ve Invested in Skillz</h2>

<p>Nothing impacts velocity more than the individual inability of the engineer to achieve tasks. This manifests itself in a blend of intelligence, experience, creativity, communication skills, passion for the product, work ethic, attention to detail, empathy for others, and the ability to suppress one’s ego for the good of the team (but, more on that later).</p>

<p>Stephen Curry is perhaps one of the greatest modern examples of a technician that has elevated his status in his field through precision practice, time commitment, and attention to detail. We refer to him often in metaphor. When I played college basketball, decades ago, I had some great mentors. I used to shoot thousands of jumpers on Saturday mornings with <a href="https://en.wikipedia.org/wiki/Ricky_Pierce">Ricky Pierce</a> and <a href="https://en.wikipedia.org/wiki/Avery_Johnson">Avery Johnson</a>. That was my first introduction to the insane amount of time it takes to become a professional. Being great is no accident, and it doesn’t stop until you retire. As CTO, the first 6 hires on our team had to be better than myself, and they had to be equally obsessed with building great software. All in all, the collective work ethic of the Den team is more than I have ever seen in any environment I have worked in.</p>

<p>As a management team, we also allow time, and invest in, our engineers. We encourage the exploration of new technologies and budget for attending conferences of their choice. In our first four months alone, we have attended WWDC, Dockercon, and Gophercon.</p>

<h2>4. We are a Team</h2>

<p>At Den, we have built a world class ‘team,’ not a group of great individuals. We are small, yet high performing, and we like it that way. High velocity and winning have no room for egos and drama. Each time we add a new personality, there is a chance we could rock our chemistry, so, we stay highly selective.</p>

<p>It also doesn’t hurt that the three founding members of Den are all former Division I collegiate athletes, having had the tenants of successful teams drilled into our heads early in life. So with that as a foundation, we were very calculated in going after the right mix of talent. All of our hires were from former organizations we had worked with in the past, or came highly recommended by a trusted colleague. The outcome of choosing the right mix is what enables the blending of our collective experience and skill sets, resulting in our ability to make sound decisions as a team.</p>

<p>Each member of our team is truly great at and passionate about what they do, and the working environment we have created is giving them the opportunity to get even better at a rapid rate.</p>

<p>Stay tuned for the technical side of our velocity strategy, as I map out our decisions from building our mobile application with Ember Cordova rather than React Native, why we chose CircleCI over Codeship, Quay as a container registry, and our combination of Node.js and Go services, thoughts about our Domain driven Microservice architecture, to details about using Terraform and Kubernetes on AWS.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[FITC Toronto 2015 and joining InVision]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2015/08/20/fitc-toronto-2015-and-joining-invision/&#8221;/>
    <updated>2015-08-20T20:28:00-05:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2015/08/20/fitc-toronto-2015-and-joining-invision</id>
    <content type="html"><![CDATA[<p><a href="https://www.youtube.com/watch?v=RoPA3xAMVvI"><img class="imgR400" alt="Jesse Cravens FITC 2014" src="http://echo 'jessecravens.com' >> source/CNAME/images/fitc2015.png&#8221;></a></p>

<p>In April, I had a chance to attend and <a href="https://www.youtube.com/watch?v=RoPA3xAMVvI">speak at FITC 2015 in Toronto</a>. This was an important talk for me as I was just three days into a new job, leaving the pond at <a href="http://frogdesign.com">frog design</a>, to join my first startup, <a href="http://invisionapp.com">InVision</a>. That was not an easy decision for me, in that I loved working for <a href="http://frogdesign.com">frog</a>. My work at <a href="http://frogdesign.com">frog</a> was the first time I had been giving the freedom to ‘focus&#8217; in the workplace.</p>

<p>The culture at frog is certainly not for everyone, but for me, someone who has always been comfortable with creating my own path, it was in many ways &lsquo;carte blanche’. The catch at <a href="http://frogdesign.com">frog</a> is that, by design, you won’t be given much direction; you are expected to create and drive the direction. When I joined <a href="http://frogdesign.com">frog</a>, my goals were to speak and write as much as I could while I focused on producing as high a volume of quality technical deliverables as I could for our clients. And in almost every case,  while leading ‘greenfield&rsquo; projects for fortune 200 companies, I was able to stop and start over on each project building upon the momentum and experience of the previous endeavor. All of that real world learning fueled my writing and speaking. It was exhausting, in the good kind of way.</p>

<p><a href="http://invisionapp.com"><img class="imgL200" alt="Jesse Cravens FITC 2014" src="http://echo 'jessecravens.com' >> source/CNAME/images/invisionapp-logo.png&#8221;></a></p>

<p>This was a very different model than building software within an enterprise, maintaining and/or augmenting legacy systems, or having frameworks and tools prescribed to you by the weight of enterprise processes and architectural directives. This was exciting because, as I said before, the freedom fueled growth, the healthy, self-directed type of growth.</p>

<p>So why did I leave? Another opportunity was presented to me that sparked a deep curiosity because in some ways the problem set was the antithesis of my work at <a href="http://frogdesign.com">frog</a>, a product suite and engineering team that was being challenged to scale to millions of users. I knew that their challenge would help me grow too, and fill in even more gaps.</p>

<p>Now, production applications weren’t new to me when I joined <a href="http://invisionapp.com">InVision</a>, but in some ways startup culture and the smaller engineering team was. While in some of my previous roles, I would be responsible for a small sliver of a very large pie, here my slice would be much larger, and the red tape would be few and far between. I could recommend an approach, build it, and deploy it within three days as compared to three months or sometimes even three years.</p>

<p>Another interesting pivot for me was to completely walk away from the Ember community, and dive into Angular and React/Flux, as if I was disgruntled with Ember or something. On the contrary, my first 3-4 months at <a href="http://invisionapp.com">InVision</a>, I spent my time retro fitting the existing application with tooling that ember-cli provides out of the box. And, as Ember 2.0 is released, my appreciation for the work that community is doing is even greater than it was before. For now, I watch from afar, as I’m not actively developing an Ember app. On the contrary, I am much closer to the Angular and React communities than I was before, which makes for a nice trade off.</p>

<p>I have to say that working at <a href="http://invisionapp.com">InVision</a> has been an amazing experience. We are a 100% remote team using the latest and greatest of tooling to keep up with each other and our software. Our software continues to evolve as does our DevOps automation, deployment models, code quality and our architecture. Not only that, we have been working night and day to build our teams with the best and brightest talent we can find. The company has tripled in the 6 months since I have been here. It has been an amazing whirlwind of growth.</p>

<p>I am currently focusing on leading the Application Core team. This was the challenge I was looking for in that I needed to learn the breadth of the product suite’s codebase before I could formalize a plan for evolving the architecture for scaling, addressing performance issues and technical debt, and improving developer workflow and code hygiene. Our application core team is now around 10 engineers and testers, and we begin to see the fruits of our labor. <a href="http://www.invisionapp.com/company">We are still growing and searching for great talent</a>, feel free to reach out if you are interested.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[What’s Next? SPA 2.0: The Latest in JavaScript Application Frameworks]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2015/02/17/whats-next-spa-2-dot-0-the-latest-in-javascript-application-frameworks/&#8221;/>
    <updated>2015-02-17T19:03:00-06:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2015/02/17/whats-next-spa-2-dot-0-the-latest-in-javascript-application-frameworks</id>
    <content type="html"><![CDATA[<h2>An Early Adopter of Ember</h2>

<p>Outside of architecting and developing complex web apps during my day job at <a href="http://frogdesign.com">frog design</a>, I spent a good part of 2014 finishing up <a href="http://www.amazon.com/gp/product/1449370926/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1449370926&linkCode=as2&tag=wwwjessecrave-20&linkId=6CCXPQ2HHNLSTI5N">Building Web Apps with Ember.js</a><img src="http://ir-na.amazon-adsystem.com/e/ir?t=wwwjessecrave-20&l=as2&o=1&a=1449370926" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />, teaching <a href="http://www.jessecravens.com/blog/2014/08/06/ember-dot-js-workshops/">Ember.js workshops</a>, and giving <a href="https://teamtreehouse.com/library/the-art-and-science-of-shipping-single-page-apps-with-emberjs">a talk entitled: “The Art and Science of Shipping of SPAs with Ember.js.”</a></p>

<p><a href="https://teamtreehouse.com/library/the-art-and-science-of-shipping-single-page-apps-with-emberjs"><img class="imgL400" alt="Jesse Cravens and The Art and Science of Shipping Single Page Apps with Ember.js" src="http://echo 'jessecravens.com' >> source/CNAME/images/blogposts/artandscience5.png&#8221;></a></p>

<p>Each of these focus areas were obviously complimentary: the workshops serving as deep dives, the talks as the high level summaries, and the book and companion source code serving as a reference application and detailed documentation.</p>

<p>At work, throughout 2013, 2014, and now into 2015, I have leveraged this momentum to educate cross-discipline teams of developers and designers and execute some very ambitious JavaScript applications for numerous clients. In a rapidly changing environment, it has been a pleasure to grow a team that now possesses framework-level expertise, allowing us to rapidly iterate on application feature sets without having to reinvent the wheel.</p>

<p><img class="imgR200" alt="O'Reilly's Building Web Apps with Ember.js by Jesse Cravens" src="http://echo 'jessecravens.com' >> source/CNAME/images/oredev/ember_cover_600.png&#8221;></p>

<p>For me, all of this has been a culmination of experiences that started in the mid 2000s with PHP and Flash work while doing small business web design and CMS development, to large scale production of JavaScript and mobile hybrid apps in the late 2000s, and to now UI/UX focused, enterprise, rapid application development.</p>

<p>Perhaps, this excerpt from the prelude of  <a href="http://www.amazon.com/gp/product/1449370926/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1449370926&linkCode=as2&tag=wwwjessecrave-20&linkId=6CCXPQ2HHNLSTI5N">Building Web Apps with Ember.js</a> explains my stance for the last couple of years:</p>

<blockquote><p>Since 2009, I have worked on numerous applications using Backbone, Angular, and
Ember. But today, I often recommend Ember.js to the clients I work with. This is primarily
due to the fact that the conventions support well-known web application development
patterns that I have custom written or pieced together from multiple open
source libraries. Here, are the high level concepts that, in my opinion, make Ember so
valuable:</p>

<ul>
<li>Ember’s object model supports a classic and well understood, object-oriented
pattern of class inheritance through extend, object initialization, getters and setters,
and class monkey patching.</li>
<li>Ember models, controllers, and components extend the Object class, which ensures
that these objects inherit Ember’s powerful default data binding.</li>
<li>The router supports complex nesting for URL-driven applications that manage
application state in a conventional way that can be understood by those with
web-server-routing backgrounds.</li>
<li>Recently, build, workflow, and testing tools in Ember have matured and become
intuitive.</li>
<li>Ember’s only dependencies are on jQuery and Handlebars.js, two very wellknown
and documented libraries.</li>
<li>Finally, the community is vibrant, passionate, and extremely active.</li>
</ul>
</blockquote>

<h2>What’s Next?</h2>

<p>Most recently, I find myself moving into a new phase that mirrors the needs and concerns of the clients I interact with on a daily basis: navigating the SPA landscape and making future friendly decisions based on the complex solutions matrix that is now Ember 2.0, Angular 2.0, and current React/Flux.</p>

<p>My latest talk:  SPA 2.0: The latest in JavaScript frameworks will address these questions:</p>

<ul>
<li><p>What does the future hold for the building of complex applications on the Web Platform in 2015?
How do we manage the complex SPA landscape, and help our clients make future friendly architectural decisions?</p></li>
<li><p>Will an Angular 2.0 breaking rewrite send devs running for something better? Can React/Flux community offer a complete application framework solution for complex applications? Will Ember continue to evolve into a lighter framework that can shed it&rsquo;s &lsquo;monolithic framework&rsquo; reputation?</p></li>
<li><p>As the Angular and React communities adopt the Ember Router and the Ember community is inspired by React’s Virtual Dom to take advantage of it’s existing under utilized view graph, the communities are adopting the best of each other. In what other ways are the individual framework communities learning from each other?</p></li>
<li><p>Will native, cross browser web components become a reality? What is the IE roadmap in regards to custom elements, HTML templates, HTML imports, and shadow DOM? Will we begin writing web components in Ember without the use of handlebars syntax?</p></li>
<li><p>Will functional reactive ‘stream’ patterns become common place with better integration into frameworks, as promises did in 2014?</p></li>
<li><p>With ES6 modules ( and transpiler build steps ), as practitioners can we finally lay the JS module debacle to rest? Do Isomorphic JS architectures still make this a challenge?</p></li>
</ul>


<h2>SPA 2.0 Topic Areas</h2>

<p>Here, are the areas my talks will focus on in 2015:</p>

<ul>
<li>Framework Maturity and Stability</li>
<li>Developer Ergonomics, Tooling, and Front End Ops</li>
<li>View Performance and Mobile</li>
<li>Async Router</li>
<li>Data Binding (1-way , 2-way use cases)</li>
<li>ES6 modules</li>
<li>Web Components</li>
<li>Community and Documentation</li>
<li>Release Cycle</li>
<li>Client Side Data Stores</li>
<li>Services and JSON Specifications</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ember.js Workshops]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2014/08/06/ember-dot-js-workshops/&#8221;/>
    <updated>2014-08-06T22:23:00-05:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2014/08/06/ember-dot-js-workshops</id>
    <content type="html"><![CDATA[<p>In the month of June, I had an opportunity to travel to Las Vegas to give a <a href="http://futureinsightslive.com/las-vegas-2014/schedule/workshop-info">workshop</a> and related <a href="http://futureinsightslive.com/las-vegas-2014/schedule/day-1">talk</a> at <a href="http://futureinsightslive.com/las-vegas-2014/">Future Insights Live 2014</a>.</p>

<p><img class="imgR400" alt="Jesse Cravens Future Insights 2014" src="http://echo 'jessecravens.com' >> source/CNAME/images/future_insights/workshop2.jpg&#8221;></p>

<p>My workshop was an 8 hour, beginner to intermediate level, course on Ember.js. I&rsquo;ve added it to our <a href="http://html5hacks.com/training">HTML Hacks</a> training content.
If you or your company need training, give us a shout.</p>

<p>Here is a brief outline of the workshop:</p>

<h1>Introducing Ember.js</h1>

<h2>Getting Started with the Starter Kit</h2>

<h2>Ember Inspector Overview</h2>

<h2>Ember Object Model</h2>

<ul>
<li>Application</li>
<li>Object Model, Inheritance, Getter and Setters, init, and .super</li>
<li>Object Model &ndash; Computed Properties</li>
<li>Object Model &ndash; Computed Properties w/ @each</li>
<li>Object Model &ndash; Observers</li>
<li>Object Model &ndash; Bindings</li>
<li>Object Model &ndash; Re-Opening Classes</li>
<li>Object Model &ndash; Mixins</li>
<li>Object Model &ndash; Enumerables</li>
</ul>


<p><img class="imgR400" alt="Jesse Cravens Future Insights 2014" src="http://echo 'jessecravens.com' >> source/CNAME/images/future_insights/workshop.jpg&#8221;></p>

<h2>Handlebars</h2>

<ul>
<li>Handlebars Templating Engine</li>
<li>With Data in an Array</li>
<li>Handlebars Helpers</li>
<li>Simple</li>
<li>Dependencies</li>
<li>Handlebars Helper to Get Bound Data</li>
</ul>


<h2>The Run Loop / Backburner</h2>

<ul>
<li>Backbone Example</li>
<li>Simple example</li>
<li>Flushing Router Transitions Queue</li>
<li>Backburner and computed properties</li>
</ul>


<h2>HTMLBars</h2>

<ul>
<li>Understanding Handlebars Metamorph</li>
<li>Ember, Backbone Benchmarks</li>
<li>HTMLBars/Backburner, Backbone, React Benchmarks</li>
<li>HTMLBars Basics: no bind-attr</li>
<li>HTMLBars Basics: no metamorphs</li>
<li>HTMLBars Basics: logic</li>
</ul>


<h2>RSVP</h2>

<ul>
<li>Simple</li>
<li>RSVP Chai-as-promised</li>
<li>RSVP and the Router &ndash; (more later)</li>
<li>RSVP.hash, RSVP.all &ndash; (more later in Views)</li>
</ul>


<h2>Router</h2>

<ul>
<li>Simple .map</li>
<li>Router and Handlebars Helpers</li>
<li>outlet</li>
<li>render</li>
<li>partial</li>
<li>Routes vs Resources</li>
<li>Async Router</li>
<li>Understand Promises</li>
<li>Understand hooks / active generation</li>
<li>Simple RSVP hash from IndexRoute</li>
<li>Nested Routes, Async Router, before/after model hooks, named outlets</li>
</ul>


<h2>Controllers</h2>

<ul>
<li>ObjectController and ArrayController</li>
<li>Controllers and Object Model</li>
<li>Hierarchy</li>
<li>Needs</li>
<li>Sorting</li>
</ul>


<h2>Views</h2>

<ul>
<li>Simple Views</li>
<li>Custom View Helpers</li>
<li>Layouts (simple handlebars compile)</li>
<li>Built In Views</li>
<li>Select</li>
</ul>


<h2>Components</h2>

<ul>
<li>Custom Elements</li>
</ul>


<h2>Actions</h2>

<h2>Ember-Data and the FixtureAdapter</h2>

<h2>Wrapping It All Together</h2>

<ul>
<li>RSVP.hash, Components, FixtureAdapter</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[BBQ, Bourbon and Ember.js at Code PaLOUsa 2014]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2014/05/01/bourbon-and-ember-dot-js-and-code-palousa-2014/&#8221;/>
    <updated>2014-05-01T08:23:00-05:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2014/05/01/bourbon-and-ember-dot-js-and-code-palousa-2014</id>
    <content type="html"><![CDATA[<p>In late April, I took my Ember.js talk to Louisville, Kentucky for the <a href="http://http://www.codepalousa.com/">CodePaLOUsa</a> conference.</p>

<p><a href="http://www.infoq.com/presentations/demo-emberjs"><img class="imgR400" alt="O'Reilly's Building Web Apps with Ember.js" src="http://echo 'jessecravens.com' >> source/CNAME/images/codepalousa14.png&#8221;></a></p>

<p>In the process I discovered <a href="http://doccrows.com/">Doc Crow&rsquo;s Southern Smokehouse and Raw Bar&rsquo;s</a> BBQ and Bourbon menu. I highly recommend it for anyone in the area trying to find authentic, local fare.</p>

<p>During the day, I also listened to some great talks from <a href="https://twitter.com/sireb">@sireb</a> and <a href="https://twitter.com/robtarr">@robtarr</a>.</p>

<p>My presentation focused on demoing the latest versions of <a href="https://github.com/emberjsbook">RockNRollCall demo application</a>, the source code for my upcoming book, <a href="http://shop.oreilly.com/product/0636920030782.do">OReilly&rsquo;s Building Web Apps with Ember.js</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[HTML5 and Ember.js at Øredev 2013:The Arts in Malmö, Sweden]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2013/12/07/html5-and-ember-dot-js-at-oredev-2013-the-arts-malmo/&#8221;/>
    <updated>2013-12-07T23:25:00-06:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2013/12/07/html5-and-ember-dot-js-at-oredev-2013-the-arts-malmo</id>
    <content type="html"><![CDATA[<p>At the beginning of November, I was given an opportunity to give two talks in Malmö, Sweden at the Øredev conference. First of all, I have to say I was extremely impressed with the conference. Although the theme was the Arts, I found it to be a developer&rsquo;s conference with an artsy edge. The speakers I had a chance to see were developer&rsquo;s developers, one of my favorites being a talk on Meteor by Chris Mather (@eventedmind) of <a href="http://eventedmind.com">eventedmind.com</a>. I&rsquo;ve maintained a peripheral view of Meteor, so it was good to get a beginner to intermediate overview of its capabilities. Given that I have been doing <a href="http://www.mongodb.com/">MongoDB</a> / <a href="https://github.com/emberjs/data">Ember-data</a> client work as of lately, I am particularly interested in exploring <a href="https://github.com/slacy/minimongo">minimongo</a>.</p>

<p><img class="imgR400" alt="Jesse Cravens at Øredev 2013 HTML5 Hacks" src="http://echo 'jessecravens.com' >> source/CNAME/images/oredev/html5hacks-oredev.jpg&#8221;></p>

<p>The city of <a href="http://en.wikipedia.org/wiki/Malm%C3%B6">Malmö</a> was also a pleasure to experience, and as you might imagine, the people of Sweden were very welcoming. One of the highlights for me was the speaker dinner at the <a href="http://en.wikipedia.org/wiki/File:Jorchr-Malm%C3%B6_r%C3%A5dhus.jpg">Malmö City Hall</a>, originally constructed in the Middle Ages. On a side note, I finally had a chance to meet and have dinner with <a href="http://www.crockford.com/">Douglass Crockford</a>, a long time inspiration and virtual mentor, who was in town to give the keynote on <a href="http://oredev.org/2013/wed-fri-conference/managing-asynchronicity-with-rq">Managing Async with RQ</a>.</p>

<iframe src="http://echo 'jessecravens.com' >> source/CNAME//player.vimeo.com/video/78847391&#8221; width=&#8221;500&#8221; height=&#8221;300&#8221; frameborder=&#8221;0&#8221; webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>


<p>
  <a href="http://vimeo.com/78847391">Building Web Applications with Ember.js and Ruby On Rails</a>
  from
  <a href="http://vimeo.com/user4280938">&Oslash;redev Conference</a>
  on
  <a href="https://vimeo.com">Vimeo</a>
  .
</p>


<p>My first talk was a preview of my new book <a href="https://github.com/emberjsbook">O&#8217;Reilly&rsquo;s Building Web Apps with Ember.js</a>. I shared the stage with co-author and fellow frog, <a href="http://bashmodernquantity.com/about/">Thomas Q. Brady</a>. We took the audience through the creation of <a href="https://github.com/emberjsbook/rocknrollcall">RocknRollCall</a>, an intermediate level <a href="http://emberjs.com/">Ember.js</a> application that fills in many of the blanks that most of the &lsquo;Getting Started&rsquo; applications don&rsquo;t.</p>

<p><img class="imgL400" alt="O'Reilly's Building Web Apps with Ember.js by Jesse Cravens" src="http://echo 'jessecravens.com' >> source/CNAME/images/oredev/ember_cover_600.png&#8221;></p>

<p>Some of the highlights of the book, and the talk, cover topics such as: a survey of Ember tooling, debugging with the <a href="https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi?hl=en">Ember Inspector</a>, Ember boilerplates, app initializers, promises in Ember, the needs API, Ember components, 3rd Party JavaScript Integration (<a href="http://jquery.com/">jQuery</a>, <a href="http://d3js.org/">D3</a>), Ember testing, SPA authentication, <a href="https://github.com/emberjs/data">Ember-data</a> and other client-side persistence solutions, and remote data persistence with Ruby On Rails and Node.js.</p>

<p>My second talk was <a href="http://html5hacks.com/">HTML5 Hacks</a> Evolved, where I continue to share more hacks from by first book <a href="http://html5hacks.com">HTML5 Hacks</a>, and <a href="http://html5hacks.com/">html5hacks.com</a>. This talk is culmination of HTML5 specifications that will have you rethinking browser-based applications. Some of the highlights of this talk included: Web Workers, WebSocket w/ GeoLocation, Device Orientation, and LeapJS, Web Components / Polymer / Ember Components (Custom Elements, Shadow DOM, HTML Imports, Model Driven Views, and Local Storage.</p>

<iframe src="http://echo 'jessecravens.com' >> source/CNAME//player.vimeo.com/video/78912115&#8221; width=&#8221;500&#8221; height=&#8221;300&#8221; frameborder=&#8221;0&#8221; webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>


<p>
  <a href="http://vimeo.com/78912115">HTML5 Hacks</a>
  from
  <a href="http://vimeo.com/user4280938">&Oslash;redev Conference</a>
  on
  <a href="https://vimeo.com">Vimeo</a>
  .
</p>


<p>In 2014, I&rsquo;m retiring the HTML5 Hacks talks, to begin focusing solely on Single Page Application development in 2014. My hope is to kick out an early release of <a href="https://github.com/emberjsbook">Building Web Apps with Ember.js</a> very soon, and finish the book in early 2014. After that I&rsquo;ll be in Louisville, KY at <a href="http://www.codepalousa.com/">Code PaLOUsa</a> to continue the Ember.js roadtrip.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[JavaScript Makers: How JS is Helping Drive the Maker Movement]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2013/10/04/javascript-makers-how-js-is-helping-drive-the-maker-movement/&#8221;/>
    <updated>2013-10-04T19:02:00-05:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2013/10/04/javascript-makers-how-js-is-helping-drive-the-maker-movement</id>
    <content type="html"><![CDATA[<p>This post is mirrored from: <a href="http://html5hacks.com/blog/2013/10/04/javascript-makers-how-js-is-helping-drive-the-maker-movement/">html5hacks.com</a></p>

<p><img class="imgR300" alt="ok200 Conference" src="http://echo 'jessecravens.com' >> source/CNAME/images/200ok/200ok1.jpg&#8221;></p>

<p>I spend my days writing a lot of JavaScript, and helping companies deliver ambitious UX focused applications to the web. I <a href="http://shop.oreilly.com/product/0636920026273.do?cmp=af-code-book-product_cj_9781449334994_7080585">author books</a> on the subject, blog, and <a href="http://lanyrd.com/profile/jdcravens/">speak at conferences</a> as often as I can.</p>

<p>I work for <a href="http://frogdesign.com">frog</a>, a product design firm, that for the last forty years has been helping increase the profiles of brands like Sony and Apple through iconic design.</p>

<p>I work within a culture that has deep roots into <a href="http://en.wikipedia.org/wiki/Maker_culture">the Maker Movement</a>; A culture that was making before the Maker Movement was cool, the &ldquo;original makers&rdquo; if you will. Written upon our walls and slide decks is the tag, <a href="https://vimeo.com/24940735">&lsquo;Love What You Make&rsquo;</a>, and as you might expect many of the frogs that sit around me are craftsfolk, DIYourselfers, and tinkerers. It is not uncommon to see a flying quadcopter, a mesh sensor network of Arduinos, 3D printed prototypes, explorations in next generation gesture with the Leap Motion and Kinect, video production, motion studies, 3D modeling, along with the standard artistic mood boards and web and native mobile application wireframes. Let&rsquo;s just say there is no shortage of creativity across every medium imaginable.</p>

<h2>Sharing My Craft with my Children</h2>

<p><img class="imgL300" alt="ok200 Conference - setting up" src="http://echo 'jessecravens.com' >> source/CNAME/images/200ok/200ok2.jpg&#8221;></p>

<p>All of that being said, I&rsquo;m a parent of two young children. My little ones constantly challenge me to find ways to share quality time with them. The parents reading this know the juggling act.</p>

<p>What I try to do is architect bridges between my children&rsquo;s curiosity and the passions of others that have explored their crafts in a deep way. Myself, and my wife, being the most important of those craftsfolk.</p>

<p>If I&rsquo;m doing it right, when I spend time with my children, they should share in my excitement and passion. If I&rsquo;m doing it wrong, I&rsquo;m overwhelmed and exhausted from work. In my vision, my children should be witnessing a model of how to wake up everyday with the goal of embracing opportunity to create a combination of function and beauty within the world around them.</p>

<p><img class="imgR200" alt="Maker Faire" src="http://echo 'jessecravens.com' >> source/CNAME/images/200ok/Maker_Faire.gif&#8221;></p>

<p>So it is in this context, that I met up with Mozilla&rsquo;s Luke Crouch, and <a href="http://makerfairetulsa.com/">Tulsa Mini Maker Faire</a>&rsquo;s Scott Phillips to put together <a href="http://200ok.us/schedule/javascript-makers/">the closing keynote at the 200ok conference</a> .</p>

<h2>JavaScript Makers: How JS is Helping Drive the Maker Movement</h2>

<p>The <a href="http://200ok.us/schedule/javascript-makers/">200ok conference</a> is on track to become Oklaoma&rsquo;s premier web conference attracting a sold out crowd of web professionals from all over Oklahoma and the neighboring states. Going in, I felt as though I knew my audience well. In other words, if I spoke to them about languages they would understand, JavaScript and HTML5, my message would easily resonate. I also knew that given their location, Tulsa, OK, a presentation that touched upon work life balance and family values would immediate strike a chord as well.</p>

<p>So in the spirit of authenticity, I pretended as if getting prepared for a closing keynote dependent on hacked together hardware and software demos wasn&rsquo;t challenging enough; I made the decision to include my 6 year old son, Carter with a flying drone and a custom configured Minecraft server accessible over conference wifi. I knew this would ensure that the presentation dangled on the brink of disaster, mirroring the chaotic reality of both open hacking and parenting.</p>

<p>My thinking was that a presentation on this topic should be authentic, and reflect the reality of my proposition, not be an ivory tower, academic/authoritative talk about how to share your craft with your children. I also made sure to not prep Carter. With a loose structure in place, we took the stage and worked our way through a story that consisted of 12 open software and hardware demos that showcased JavaScript as a primary scripting language, and a table full of hardware that ranged from a drone, a dissected wifli helicopter and erector set, a leap motion, and numerous prototyping boards.</p>

<script async class="speakerdeck-embed" data-slide="10" data-id="78b4c9300a8801313e8202078d31cabc" data-ratio="1.2994923857868" src="http://echo 'jessecravens.com' >> source/CNAME//speakerdeck.com/assets/embed.js"></script>


<p>Here are some of the highlights:</p>

<h2>JavaScript and Prototyping Boards</h2>

<p>Earlier this year I did a presentation at HTML5.tx that focused on building an <a href="http://www.youtube.com/watch?v=H00_BGRkBRM">Internet of Things with JavaScript</a> and various open hardware prototyping boards such as Arduino, BeagleBone, and the Raspberry Pi. It was in that talk that I made a connection that eventually led to an introduction to Luke. So, given that the HTML5.tx content was of interest I started the presentation with a demo of the Arduino, <a href="https://github.com/rwaldron/johnny-five">Johnny Five</a>, the original Beaglebone and <a href="https://github.com/jadonk/bonescript">BoneScript</a>.</p>

<figure class='code'><figcaption><span>bonescript.js </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'>  <span class="p">...</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;bonescript&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">ledPin</span> <span class="o">=</span> <span class="nx">bone</span><span class="p">.</span><span class="nx">P8_3</span><span class="p">;</span>
</span><span class='line'>  <span class="nx">ledPin2</span> <span class="o">=</span> <span class="nx">bone</span><span class="p">.</span><span class="nx">P8_4</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="p">...</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">app</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s1">&#39;/motion&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">next</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">[</span><span class="s1">&#39;eventType&#39;</span><span class="p">]);</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">res</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="s1">&#39;Motion data collected for &#39;</span>  <span class="o">+</span> <span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">[</span><span class="s1">&#39;eventType&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="s1">&#39; event&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">[</span><span class="s1">&#39;eventType&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;motionstart&quot;</span><span class="p">){</span>
</span><span class='line'>      <span class="nx">digitalWrite</span><span class="p">(</span><span class="nx">ledPin2</span><span class="p">,</span> <span class="nx">HIGH</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">[</span><span class="s1">&#39;eventType&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;motionend&quot;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">digitalWrite</span><span class="p">(</span><span class="nx">ledPin</span><span class="p">,</span> <span class="nx">HIGH</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'>
</span></code></pre></td></tr></table></div></figure>


<h2>Nodecopter and the Leap Motion</h2>

<p>I started with the basics of the <a href="https://github.com/felixge/node-ar-drone">node-ar-drone module</a>:</p>

<figure class='code'><figcaption><span>ar-drone.js </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'>  <span class="kd">var</span> <span class="nx">arDrone</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;ar-drone&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">client</span>  <span class="o">=</span> <span class="nx">arDrone</span><span class="p">.</span><span class="nx">createClient</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">client</span><span class="p">.</span><span class="nx">takeoff</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">client</span>
</span><span class='line'>    <span class="p">.</span><span class="nx">after</span><span class="p">(</span><span class="mi">7000</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">this</span><span class="p">.</span><span class="nx">animate</span><span class="p">(</span><span class="s1">&#39;flipRight&#39;</span><span class="p">,</span> <span class="mi">1000</span><span class="p">);</span>
</span><span class='line'>      <span class="k">this</span><span class="p">.</span><span class="nx">animateLeds</span><span class="p">(</span><span class="s1">&#39;blinkRed&#39;</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
</span><span class='line'>    <span class="p">})</span>
</span><span class='line'>    <span class="p">.</span><span class="nx">after</span><span class="p">(</span><span class="mi">3000</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">this</span><span class="p">.</span><span class="nx">stop</span><span class="p">();</span>
</span><span class='line'>      <span class="k">this</span><span class="p">.</span><span class="nx">land</span><span class="p">();</span>
</span><span class='line'>    <span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Later, a crowd favorite was mapping the gestures from the <a href="https://www.leapmotion.com/">Leap Motion</a> to the <a href="http://ardrone2.parrot.com/">Parrot AR drone</a>, so that a one finger clockwise gesture triggered a nodecopter takeoff. A counter clockwise gesture then landed it. I was able to put this together using the leapJS and node-ardrone node modules, based on some initial hacking by <a href="https://twitter.com/markuskobler">Markus Kobler</a>, where he pulled this off at a <a href="https://github.com/markuskobler/nodecopter-london">Nodecopter London event</a>.</p>

<iframe src="http://echo 'jessecravens.com' >> source/CNAME//player.vimeo.com/video/75616363&#8221; width=&#8221;500&#8221; height=&#8221;281&#8221; frameborder=&#8221;0&#8221; webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>


<p> <p><a href="http://vimeo.com/75616363">Jesse Cravens blowing minds with a JS-driven copter.</a> from <a href="http://vimeo.com/user21333523">Michael Gorsuch</a> on <a href="https://vimeo.com">Vimeo</a>.</p></p>

<h2>ScriptCraft: Running JavaScript from within Minecraft</h2>

<p><img class="imgL300" alt="ok200 Conference" src="http://echo 'jessecravens.com' >> source/CNAME/images/200ok/200ok3.jpg&#8221;></p>

<p>Later, I showed how to script inside of the Minecraft virtual world, using <a href="https://twitter.com/walter">Walter Higgins&#8217;</a> great <a href="https://github.com/walterhiggins/ScriptCraft">ScriptCraft library</a>. I wasn&rsquo;t expecting the conference wifi, and single access point, to suffice in allowing Carter and I to interact within virtual world. I was also concerned about the dynamic IP, and having to change it on the fly, start/restart the server, etc. So I made the decision 10 minutes before to not have Carter log in, and I would just speak to the possibility instead. In true 6 year old fashion, he rebelled and logged onto my server, popping up in front of me wearing a Creeper mask, as I was mid stream explaining how to script wooden signs with his 1st grade sight words as a homework exercise.</p>

<figure class='code'><figcaption><span>sightwords.js </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="nx">Drone</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="s1">&#39;sightwords&#39;</span><span class="p">,</span><span class="kd">function</span> <span class="p">(){</span>
</span><span class='line'>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">wordsArr</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;have&quot;</span><span class="p">,</span> <span class="s2">&quot;black&quot;</span><span class="p">,</span> <span class="s2">&quot;three&quot;</span><span class="p">,</span> <span class="s2">&quot;want&quot;</span><span class="p">,</span> <span class="s2">&quot;get&quot;</span><span class="p">,</span> <span class="s2">&quot;how&quot;</span><span class="p">,</span> <span class="s2">&quot;two&quot;</span><span class="p">,</span> <span class="s2">&quot;ten&quot;</span><span class="p">,</span> <span class="s2">&quot;come&quot;</span><span class="p">,</span> <span class="s2">&quot;went&quot;</span><span class="p">,</span> <span class="s2">&quot;into&quot;</span><span class="p">,</span> <span class="s2">&quot;know&quot;</span><span class="p">,</span> <span class="s2">&quot;my&quot;</span><span class="p">,</span> <span class="s2">&quot;do&quot;</span><span class="p">,</span> <span class="s2">&quot;down&quot;</span><span class="p">,</span> <span class="s2">&quot;who&quot;</span><span class="p">,</span> <span class="s2">&quot;must&quot;</span><span class="p">,</span> <span class="s2">&quot;let&quot;</span><span class="p">,</span> <span class="s2">&quot;with&quot;</span><span class="p">,</span> <span class="s2">&quot;red&quot;</span><span class="p">,</span> <span class="s2">&quot;find&quot;</span><span class="p">,</span> <span class="s2">&quot;will&quot;</span><span class="p">,</span> <span class="s2">&quot;new&quot;</span><span class="p">,</span> <span class="s2">&quot;live&quot;</span><span class="p">,</span> <span class="s2">&quot;five&quot;</span><span class="p">,</span> <span class="s2">&quot;you&quot;</span><span class="p">,</span> <span class="s2">&quot;funny&quot;</span><span class="p">,</span> <span class="s2">&quot;yes&quot;</span><span class="p">,</span> <span class="s2">&quot;no&quot;</span><span class="p">,</span> <span class="s2">&quot;may&quot;</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">for</span> <span class="p">(</span><span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span><span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">wordsArr</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">){</span>
</span><span class='line'>        <span class="k">this</span><span class="p">.</span><span class="nx">right</span><span class="p">(</span><span class="mi">0</span><span class="o">+</span><span class="nx">i</span><span class="p">).</span><span class="nx">sign</span><span class="p">(</span><span class="nx">wordsArr</span><span class="p">[</span><span class="nx">i</span><span class="p">],</span><span class="mi">68</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">move</span><span class="p">(</span><span class="s1">&#39;sightwords&#39;</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Needless to say, his innapropriate behavior was a crowd favorite. I have to admit, it was mine as well.</p>

<p><img class="imgR300" alt="ok200 Conference" src="http://echo 'jessecravens.com' >> source/CNAME/images/200ok/200ok4.png&#8221;></p>

<p>Going into the talk, I knew I&rsquo;d either be trying this again in the future or abandoning it as &lsquo;one of those ideas&rsquo; that sounded good in theory, but was just not going to work. Where did I land? Well, let&rsquo;s just say that Carter and I are looking for our next opportunity to share our experiences with other parents/web professionals.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Debugging Modern Web Applications Part 1]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2013/09/06/debugging-modern-web-applications-part-1/&#8221;/>
    <updated>2013-09-06T19:43:00-05:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2013/09/06/debugging-modern-web-applications-part-1</id>
    <content type="html"><![CDATA[<p>As JavaScript-centric web applications continue to become the standard, and the browser continues to evolve into a full-featured web application platform, developers need powerful debugging tools to help quickly troubleshoot issues and fix them efficiently. Issues can range from HTML/CSS browser inconsistencies, JavaScript exceptions, and a myriad of performance issues that range from DOM access to network latency.</p>

<p>There a number of tools that web developers can use to help make debugging front end applications less painful.</p>

<p><img class="imgR400" alt="Debugging Modern Web Applications" src="http://tpstatic.com/img/usermedia/KRuw_KM2X0GCCs9xf497KA/original.png"></p>

<p>In this tutorial, we will walk through the top tools available and how to use these tools by addressing some of the most common issues faced in modern web application. This is a beginner to intermediate level tutorial for web developers getting started with debugging the web, or programmers coming from other languages who want to better understand how to troubleshoot client side JavaScript, the DOM, performance, and network calls.</p>

<p>To demonstrate we will be debugging a simple web application. The source code is available here: <a href="https://github.com/jessecravens/techpro-debugging.">https://github.com/jessecravens/techpro-debugging.</a></p>

<p>Read more at: <a href="http://tech.pro/tutorial/1404/debugging-modern-web-applications-part-1">http://tech.pro/tutorial/1404/debugging-modern-web-applications-part-1</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Web Worker Patterns]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2013/08/26/web-worker-patterns/&#8221;/>
    <updated>2013-08-26T14:03:00-05:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2013/08/26/web-worker-patterns</id>
    <content type="html"><![CDATA[<p>JavaScript is executed in a single thread. If you&rsquo;re not familiar with threads, what this means is that JavaScript can only execute one block of code at a time. If code is already executing, any interaction by the user will instantiate an asynchronous event that is queued up for later execution. Other events like those from XMLHttpRequests and timers, are also added to the queue.</p>

<p>So, as you might expect, a single-threaded architecture can be problematic to the user experience if a particular script takes a long time to complete.</p>

<p>Read more at: <a href="http://tech.pro/tutorial/1487/web-worker-patterns">http://tech.pro/tutorial/1487/web-worker-patterns</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Building Next Generation Widgets with Web Components]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2013/07/25/building-next-generation-widgets-with-web-components/&#8221;/>
    <updated>2013-07-25T03:41:00-05:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2013/07/25/building-next-generation-widgets-with-web-components</id>
    <content type="html"><![CDATA[<p><img class="imgL400" alt="Nerdclustr" src="http://tpstatic.com/img/usermedia/9ylQdMSRLUiffrQPG4hHJw/original.png"></p>

<p>For SXSWi and FluentConf this year, <a href="http://twitter.com/boyofgreen">@boyofgreen</a> and I created a demo application to showcase some of the hacks that we included in our book OReilly&rsquo;s HTML5 Hacks.</p>

<p>The demo application, Nerdclustr, is an HTML5 mobile application that brings &lsquo;nerds&rsquo; of all types together conferences and provides a visual map that updates in real time. The application was written with Node.js and the Express web framework. It demonstrates the following specifications: HTML5 Web Forms, Geo Location API, WebSocket, Canvas, CSS3 transforms.</p>

<p>Given, the attention that Web Components and <a href="http://www.polymer-project.org/polymer.html">Polymer.js</a> have been getting lately, I felt this was a good opportunity to demonstrate some of the exciting new specifications that are making their way to modern browsers. For the sake of this tutorial, I&rsquo;ll be using and providing screenshots of Google Chrome, but it should be worth your time to explore the status of each of the specifications in other modern browsers as well.</p>

<p>In this tutorial, we will take a look at the HTML5 specs mentioned above in detail. Then, we will explore Polymer.js and build out an example application.</p>

<p>Read more at: <a href="http://tech.pro/tutorial/1421/building-next-generation-widgets-with-web-components">http://tech.pro/tutorial/1421/building-next-generation-widgets-with-web-components</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Fluent Conf 2013: Battle of the HTML5 Hackers]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2013/06/05/fluent-conf-2013-battle-of-the-html5-hackers/&#8221;/>
    <updated>2013-06-05T10:12:00-05:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2013/06/05/fluent-conf-2013-battle-of-the-html5-hackers</id>
    <content type="html"><![CDATA[<p>Our presentation at Fluent Conference 2013 was a success, as <a href="https://twitter.com/boyofgreen">Jeff</a> and I delivered our final version of the &lsquo;Battle of the Hackers&rsquo; series.</p>

<p><img class="imgR300" alt="Jesse Cravens - Fluent Conf 2013" src="http://echo 'jessecravens.com' >> source/CNAME/images/fluent_video.png&#8221;></p>

<p>If you missed the conference, you can still catch every workshop, session, and keynote with the complete video compilation of the event.Catch up with this year’s lineup of speakers—seasoned pros as well as notable newcomers—as they share their expertise with JavaScript, HTML5, CSS, and related technologies that power the Web.</p>

<p>You can order the series <a href="http://shop.oreilly.com/product/0636920030843.do">here</a>.</p>

<p><img class="imgL200" alt="Jesse Cravens - Fluent Conf 2013" src="http://echo 'jessecravens.com' >> source/CNAME/images/jesse_fluent.png&#8221;></p>

<p>It was a great pleasure to share the stage with Brendan Eich (Mozilla), Paul Irish (Google), Lea Verou (W3C), Bill Scott (PayPal), Jesse Freeman (Microsoft), Dion Almaer (Walmart.com), and dozens more in the field.</p>

<p>We also had a great turn out for the book signing, thanks for all the support. And congrats to Doug Hall for winning a free ebook copy of our book <a href="http://shop.oreilly.com/product/0636920026273.do">HTML5 Hacks</a></p>

<p><img class="imgR300" alt="Jesse Cravens - Fluent Conf 2013" src="http://echo 'jessecravens.com' >> source/CNAME/images/fluent_books.jpg&#8221;></p>

<p>As always we&rsquo;ve made all the code available and more at <a href="http://html5hacks.com">html5hacks.com</a>, and on github: <a href="http://github.com/html5hacks">github.com/html5hacks</a>.</p>

<p>I also added a few more new hacks, involoving Web Components (Shadow DOM, HTML Imports, Custom Elements) and Polymer.js. You can find that source code available here: <a href="https://github.com/html5hacks/fluent2013-html5hacks">github.com/html5hacks/fluent2013-html5hacks</a></p>

<p>It&rsquo;s been alot of fun co-presenting with Jeff, but my next two sessions, I will be going at HTML5 Hacking solo. You can catch my next presentations in NYC on July 24th–25th at <a href="http://lanyrd.com/2013/devcon5/">Devcon5 2013 NYC</a> or November 4th–8th at <a href="http://lanyrd.com/2013/redev/">Øredev 2013</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ember.js Views and Live Templates with Handlebars.js Part 1]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2013/06/04/ember-dot-js-views-and-live-templates-with-handlebars-dot-js-part-1/&#8221;/>
    <updated>2013-06-04T10:05:00-05:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2013/06/04/ember-dot-js-views-and-live-templates-with-handlebars-dot-js-part-1</id>
    <content type="html"><![CDATA[<p><img class="imgL200" alt="Tech-pro Ember.js Views" src="http://tpstatic.com/img/usermedia/cHI1WdevsEyBJ7dLfmVUdA/cropped-w220-h220.png"></p>

<p>This is an exploration of Handlebars.js template library when used with Ember.js views. Many of the Handlebars.js tutorials on the web discuss the Handlebars API, but not in the specific context of using Handlebars with Ember.js. In addition to filling that void, I&rsquo;ll also give a brief background of JavaScript templating in general to provide perspective as to the problems it is solving.</p>

<p>This tutorial will be divided into two parts. In Part 1, you should gain a clear understanding of JavaScript templates, the capabilities of Handlebars expressions and helpers, and how to write your own Handlebars helpers.</p>

<p>Read more at: <a href="http://tech.pro/tutorial/1308/emberjs-views-and-live-templates-with-handlebarsjs-part-1">http://tech.pro/tutorial/1308/emberjs-views-and-live-templates-with-handlebarsjs-part-1</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Modern Ember.js Application Workflow with Yeoman and Mocha]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2013/04/23/modern-ember-dot-js-application-workflow-with-yeoman-and-mocha/&#8221;/>
    <updated>2013-04-23T10:05:00-05:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2013/04/23/modern-ember-dot-js-application-workflow-with-yeoman-and-mocha</id>
    <content type="html"><![CDATA[<p><img class="imgL200" alt="Tech-pro Modern Ember.js Application Workflow" src="http://tpstatic.com/img/usermedia/LgFpf2qDCkGfHlDBR4oGDA/cropped-w220-h220.png"></p>

<p>The following tutorial will provide an overview for building Ember.js applications with Yeoman. Keep in mind, Yeoman is a framework agnostic collection of tools, used to manage the workflow of any JavaScript application or plugin. For the sake of this tutorial, we have chosen to focus on Ember.js, as a case study.</p>

<p>Our workflow would not be complete without also setting up our testing strategy, so we will also include a standard BDD (Behavior Driven Development) setup with the Mocha testing framework.</p>

<p>Read more at: <a href="http://tech.pro/tutorial/1249/modern-emberjs-application-workflow-with-yeoman-and-mocha">http://tech.pro/tutorial/1249/modern-emberjs-application-workflow-with-yeoman-and-mocha</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Push Notifications to the Browser with Server Sent Events]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2013/04/21/push-notifications-to-the-browser-with-server-sent-events/&#8221;/>
    <updated>2013-04-21T15:44:00-05:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2013/04/21/push-notifications-to-the-browser-with-server-sent-events</id>
    <content type="html"><![CDATA[<p>Mirrored from: <a href="http://html5hacks.com/blog/2013/04/21/push-notifications-to-the-browser-with-server-sent-events/">http://html5hacks.com/blog/2013/04/21/push-notifications-to-the-browser-with-server-sent-events/</a></p>

<p>Created by Opera, Server Sent Events standardizes Comet technologies. The standard intends to enable native real time updates through a simple JavaScript API called EventSource, which connects to servers that asynchronously push data updates to clients via HTTP Streaming. Server Sent Events use a single, unidirectional, persistent connection between the browser and the server.</p>

<p>Unlike the Web Socket API, Server Sent Events and EventSource object use HTTP to enable real-time server push capabilities within your application. HTTP Streaming predates the WebSocket API, and it is often referred to as Comet or server push. The exciting part here is that the Server Sent Events API intends to standardize the Comet technique, making it trivial to implement in the browser.</p>

<h2>What is HTTP Streaming?</h2>

<p>In a standard HTTP request and response between a web browser and a web server, the server will close the connection once it has completed the processing of the request. HTTP streaming, or Comet, differs in that the server maintains a persistent, open connection with the browser.</p>

<p>It is important to note that not all web servers are capable of streaming. Only evented servers such as Node.js, Tornado, or Thin are equipped incorporate an event loop that is optimal for supporting HTTP streaming. These, non-blocking servers handle persistent connections from a large number of concurrent requests very well.</p>

<p>A complete discussion on evented vs. threaded servers is out of scope for this post, but that being said, in the upcoming hack we will provide a very simple evented server implementation example to get you started. We provide a simple browser based JavaScript to connect to the server, and a server side implementation using Ruby, Thin, and Sinatra.
For the record, this is also very easy to do with Node.js.</p>

<p>Here is a link to the companion github repository:
<a href="https://github.com/html5hacks/chapter9">https://github.com/html5hacks/chapter9</a></p>

<h2>Ruby’s Sinatra</h2>

<p>The Sinatra documentation describes itself as a “DSL for quickly creating web applications in Ruby with minimal effort.”
This text has focused primarily on Node.js (HTTP Server) and Express.js (web application framework) to quickly generate server side implementations for hacking out functionality.</p>

<p>It would a disservice to not mention Ruby, Rails and Sinatra in the same or similar light as we have Node.js in this text. Although learning Ruby is another learning curve, in the larger scheme of programming languages it is a less daunting curve than most. And as most die-hard Rubyists will preach, it is arguably the most elegant and fun to write of all modern programming languages. Ruby on Rails, and its little brother Sinatra are also great web application frameworks to start with if you are new to web application development.</p>

<p>Much like Node.js and Express, Sinatra makes building small server implementations nearly trivial. So for the context of HTML5 Hacks, that allows us to focus our efforts on programming in the browser.</p>

<p>For now let’s build a simple HTTP Streaming server using Sinatra.</p>

<p>To get started with Ruby On Rails or Sinatra, check out the great documentation available at <a href="http://guides.rubyonrails.org/getting_started.html">http://guides.rubyonrails.org/getting_started.html</a> and <a href="http://sinatrarb.com/intro">http://sinatrarb.com/intro</a>, respectively.</p>

<h2>Building Push Notifications</h2>

<p>Our goal in the next hack is to build a simple streaming server and use the EventSource object to open a persistent connection from the browser. We will then push notifcations from one ‘admin’ browser to all the connected receivers. Sounds simple, right? Let’s get started.</p>

<h2>A Simple HTTP Streaming Server</h2>

<p>Open up a file and name it stream.rb. Then add the following:
Simple requiring of Sinatra and the JSON library:</p>

<figure class='code'><figcaption><span>stream.rb </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'>  <span class="nb">require</span> <span class="s1">&#39;json&#39;</span>
</span><span class='line'>  <span class="nb">require</span> <span class="s1">&#39;sinatra&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Then, we set up a public folder, and set the server to use the evented ruby server, Thin.</p>

<figure class='code'><figcaption><span>stream.rb </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'>  <span class="n">set</span> <span class="ss">:public_folder</span><span class="p">,</span> <span class="no">Proc</span><span class="o">.</span><span class="n">new</span> <span class="p">{</span> <span class="no">File</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="s2">&quot;public&quot;</span><span class="p">)</span> <span class="p">}</span>
</span><span class='line'>  <span class="n">set</span> <span class="ss">server</span><span class="p">:</span> <span class="s1">&#39;thin&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Set up two routs for serving our 2 pages: index and admin. We will use Erb as our templating language. The details are out of scope, but our use is very minimal. More on Erb here: <a href="http://ruby-doc.org/stdlib-1.9.3/libdoc/erb/rdoc/ERB.html">http://ruby-doc.org/stdlib-1.9.3/libdoc/erb/rdoc/ERB.html</a></p>

<figure class='code'><figcaption><span>stream.rb </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'>  <span class="n">get</span> <span class="s1">&#39;/&#39;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">erb</span> <span class="ss">:index</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">get</span> <span class="s1">&#39;/admin&#39;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">erb</span> <span class="ss">:admin</span>
</span><span class='line'>  <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>We’d like to timestamp each notification, so here is a very simple function definition.</p>

<figure class='code'><figcaption><span>stream.rb </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'>  <span class="k">def</span> <span class="nf">timestamp</span>
</span><span class='line'>    <span class="no">Time</span><span class="o">.</span><span class="n">now</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">&quot;%H:%M:%S&quot;</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>We also set up two empty arrays: one to hold the connections and the other to hold out notifications.</p>

<figure class='code'><figcaption><span>stream.rb </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'>  <span class="n">connections</span> <span class="o">=</span> <span class="o">[]</span>
</span><span class='line'>  <span class="n">notifications</span> <span class="o">=</span> <span class="o">[]</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now, for the routes. When our browser loads it s page, we have JavaScript running which will use the EventSource object to connect to a url here: <a href="http://localhost:4567/connect.">http://localhost:4567/connect.</a></p>

<p>More on EventSource later.</p>

<p>But for now you can see the magic of the evented HTTP stream, the connection is held open until a callback is fired to close the stream.</p>

<figure class='code'><figcaption><span>stream.rb </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'>  <span class="n">get</span> <span class="s1">&#39;/connect&#39;</span><span class="p">,</span> <span class="ss">provides</span><span class="p">:</span> <span class="s1">&#39;text/event-stream&#39;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">stream</span> <span class="ss">:keep_open</span> <span class="k">do</span> <span class="o">|</span><span class="n">out</span><span class="o">|</span>
</span><span class='line'>      <span class="n">connections</span> <span class="o">&lt;&lt;</span> <span class="n">out</span>
</span><span class='line'>
</span><span class='line'>      <span class="c1">#out.callback on stream close evt. </span>
</span><span class='line'>      <span class="n">out</span><span class="o">.</span><span class="n">callback</span> <span class="p">{</span>
</span><span class='line'>        <span class="c1">#delete the connection </span>
</span><span class='line'>        <span class="n">connections</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span><span class="n">out</span><span class="p">)</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Finally, any data this posted to the /push route is pushed out to each connected device.</p>

<figure class='code'><figcaption><span>stream.rb </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'>  <span class="n">post</span> <span class="s1">&#39;/push&#39;</span> <span class="k">do</span>
</span><span class='line'>    <span class="nb">puts</span> <span class="n">params</span>
</span><span class='line'>    <span class="c1">#Add the timestamp to the notification</span>
</span><span class='line'>    <span class="n">notification</span> <span class="o">=</span> <span class="n">params</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span> <span class="p">{</span><span class="s1">&#39;timestamp&#39;</span> <span class="o">=&gt;</span> <span class="n">timestamp</span><span class="p">})</span><span class="o">.</span><span class="n">to_json</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">notifications</span> <span class="o">&lt;&lt;</span> <span class="n">notification</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">notifications</span><span class="o">.</span><span class="n">shift</span> <span class="k">if</span> <span class="n">notifications</span><span class="o">.</span><span class="n">length</span> <span class="o">&gt;</span> <span class="mi">10</span>
</span><span class='line'>    <span class="n">connections</span><span class="o">.</span><span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">out</span><span class="o">|</span> <span class="n">out</span> <span class="o">&lt;&lt;</span> <span class="s2">&quot;data: </span><span class="si">#{</span><span class="n">notification</span><span class="si">}</span><span class="se">\n\n</span><span class="s2">&quot;</span><span class="p">}</span>
</span><span class='line'>  <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>As we said before, you can just follow the instructions at our git repository to pull down and build this code. Or if you have been following along, launch a terminal, navigate to the directory where you code is, and run:</p>

<figure class='code'><figcaption><span>cli </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ ruby stream.rb</span></code></pre></td></tr></table></div></figure>


<p>Figure 9.15 Starting the Sinatra Server</p>

<p><img class="figure" alt="Figure 7-2" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter9-images/9-15.png&#8221;></p>

<p>Alright, so now that we have out Sinatra app up and running with custom routes to handle incoming requests from our browser.</p>

<p>If this doesn’t make complete sense yet, just hang loose. In the upcoming subsections, the rest of the items will start to fall into place.</p>

<h2>Set Up the HTML pages</h2>

<p>We will be building 2 pages: one for the admin to push out notifications, and the other will be for the connected receivers to receive the notification. Both of these ‘views’ will share the same layout, as such:</p>

<figure class='code'><figcaption><span>index.html </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;html&gt;</span>
</span><span class='line'>  <span class="nt">&lt;head&gt;</span>
</span><span class='line'>    <span class="nt">&lt;title&gt;</span>HTML5 Hacks - Server Sent Events<span class="nt">&lt;/title&gt;</span>
</span><span class='line'>    <span class="nt">&lt;meta</span> <span class="na">charset=</span><span class="s">&quot;utf-8&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>
</span><span class='line'>    <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">”http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js”</span><span class="nt">&gt;</span>
</span><span class='line'><span class="nt">&lt;/script&gt;</span>
</span><span class='line'>    <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.js&quot;</span><span class="nt">&gt;</span> <span class="nt">&lt;/script&gt;</span>
</span><span class='line'>    <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;jquery.notify.js&quot;</span> <span class="na">type=</span><span class="s">&quot;text/javascript&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
</span><span class='line'>    <span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">&quot;stylesheet&quot;</span> <span class="na">type=</span><span class="s">&quot;text/css&quot;</span> <span class="na">href=</span><span class="s">&quot;style.css&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">&quot;stylesheet&quot;</span> <span class="na">type=</span><span class="s">&quot;text/css&quot;</span> <span class="na">href=</span><span class="s">&quot;ui.notify.css&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="nt">&lt;/head&gt;</span>
</span><span class='line'>  <span class="nt">&lt;body&gt;</span>
</span><span class='line'>    <span class="cp">&lt;!—- implementation specific here --&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/body&gt;</span>
</span><span class='line'><span class="nt">&lt;/html&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The admin page will contain an input tag and a simple button.</p>

<figure class='code'><figcaption><span>admin.html </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;wrapper&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;text&quot;</span> <span class="na">id=</span><span class="s">&quot;message&quot;</span> <span class="na">placeholder=</span><span class="s">&quot;Enter Notification Here&quot;</span> <span class="nt">/&gt;&lt;br&gt;</span>
</span><span class='line'>    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">”button”</span> <span class="na">id=</span><span class="s">&quot;send&quot;</span> <span class="na">data-role=</span><span class="s">&quot;button&quot;</span><span class="nt">&gt;</span>push<span class="nt">&lt;/input&gt;</span>
</span><span class='line'><span class="nt">&lt;/div&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>And our receiver pages will display a simple piece of text:</p>

<figure class='code'><figcaption><span>receiver.html </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;wrapper&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="nt">&lt;p&gt;</span>Don&#39;t Mind me ... Just Waiting for a Push Notification from HTML5 Hacks.<span class="nt">&lt;/p&gt;</span>
</span><span class='line'><span class="nt">&lt;/div&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>By launching one browser window to <a href="http://localhost:4567/admin">http://localhost:4567/admin</a> you should now see our admin form.</p>

<p>Figure 9.16 The initial admin page</p>

<p><img class="figure" alt="Figure 9-16" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter9-images/9-16.png&#8221;></p>

<p>And, navigate to <a href="http://localhost:4567">http://localhost:4567</a> in your browser and you should see.</p>

<p>Figure 9.17 The initial index page</p>

<p><img class="figure" alt="Figure 9-17" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter9-images/9-17.png&#8221;></p>

<h2>Adding a bit of jQuery</h2>

<p>We need to add a bit of JavaScript to attach an event listener to the “send” button. This snippet will prevent the default submission of the form and post the notifcation object to the server as JSON.
Notice the url /push maps to the route we defined in our Sinatra app.</p>

<figure class='code'><figcaption><span>push.js </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#send&#39;</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">event</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>   <span class="kd">var</span> <span class="nx">notifcation</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">notifcation</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#notification&#39;</span><span class="p">).</span><span class="nx">val</span><span class="p">()};</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">$</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span> <span class="s1">&#39;/push&#39;</span><span class="p">,</span> <span class="nx">notifcation</span><span class="p">,</span><span class="s1">&#39;json&#39;</span><span class="p">);</span>
</span><span class='line'> <span class="p">})</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now, lets open up five browser windows: one admin at <a href="http://localhost:4567/admin">http://localhost:4567/admin</a> and four more receivers at <a href="http://localhost:4567">http://localhost:4567</a></p>

<p>Figure 9.18 Opening 5 browser windows</p>

<p><img class="figure" alt="Figure 9-18" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter9-images/9-18.png&#8221;></p>

<p>Looking good.</p>

<p>But before we get started, lets set up our EventSource.</p>

<h2>EventSource</h2>

<p>Event Source is a super simple JavaScript API for opening a connection with an HTTP stream.
Because our receiver pages are just ‘dumb’ terminals that receive data, we have an ideal scenario for Server Side Events.
Earlier, when we discussed the Sinatra app, we showed exposing a route for the browser to connect to an HTTP stream. Well, this is where we connect!</p>

<figure class='code'><figcaption><span>es.js </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'>  <span class="kd">var</span> <span class="nx">es</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventSource</span><span class="p">(</span><span class="s1">&#39;/connect&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">es</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">msg</span> <span class="o">=</span> <span class="nx">$</span><span class="p">.</span><span class="nx">parseJSON</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// … do something</span>
</span><span class='line'>  <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now we can add a simple notification with the available data,</p>

<figure class='code'><figcaption><span>es.js </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'>  <span class="kd">var</span> <span class="nx">es</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventSource</span><span class="p">(</span><span class="s1">&#39;/connect&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">es</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">msg</span> <span class="o">=</span> <span class="nx">$</span><span class="p">.</span><span class="nx">parseJSON</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// … Notify</span>
</span><span class='line'>  <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>And here is the final script for the admin:</p>

<figure class='code'><figcaption><span>es.js </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'>  <span class="nx">$</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#send&#39;</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">event</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>      <span class="kd">var</span> <span class="nx">notification</span> <span class="o">=</span> <span class="p">{</span><span class="nx">message</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#notification&#39;</span><span class="p">).</span><span class="nx">val</span><span class="p">()};</span>
</span><span class='line'>
</span><span class='line'>      <span class="nx">$</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span> <span class="s1">&#39;/push&#39;</span><span class="p">,</span> <span class="nx">notification</span><span class="p">,</span><span class="s1">&#39;json&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="p">})</span>
</span><span class='line'>  <span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Installing jQuery.notify</h2>

<p>For our Push Notifcations we will make use of Eric Hynds great jQuery plugin jquery-notify, located here at github: [github.com/ehynds/jquery-notify] (<a href="https://github.com/ehynds/jquery-notify">https://github.com/ehynds/jquery-notify</a>)</p>

<p>In order to display the notification, we will need to include some markup to the receiver page.</p>

<figure class='code'><figcaption><span>receiver.html </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;container&quot;</span> <span class="na">style=</span><span class="s">&quot;display:none&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;basic-template&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>        <span class="nt">&lt;a</span> <span class="na">class=</span><span class="s">&quot;ui-notify-cross ui-notify-close&quot;</span> <span class="na">href=</span><span class="s">&quot;#&quot;</span><span class="nt">&gt;</span>x<span class="nt">&lt;/a&gt;</span>
</span><span class='line'>        <span class="nt">&lt;h1&gt;</span>#{title}<span class="nt">&lt;/h1&gt;</span>
</span><span class='line'>        <span class="nt">&lt;p&gt;</span>#{text}<span class="nt">&lt;/p&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/div&gt;</span>
</span><span class='line'><span class="nt">&lt;/div&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>This creates a hidden div tag in the bottom of the document. We are not showing the CSS that uses “display: none” to hide it, but you can see more by examining the source code in the companion git repo.</p>

<p>Figure 9.19 Inspecting the DOM in Chrome Dev Tools</p>

<p><img class="figure" alt="Figure 9-19" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter9-images/9-19.png&#8221;></p>

<p>In order for jQuery.notify to initialize, you must first call the following:</p>

<figure class='code'><figcaption><span>es.js </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#container&quot;</span><span class="p">).</span><span class="nx">notify</span><span class="p">({</span>
</span><span class='line'>  <span class="nx">speed</span><span class="o">:</span> <span class="mi">500</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">expires</span><span class="o">:</span> <span class="kc">false</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>And here is the final script for the receiver:</p>

<figure class='code'><figcaption><span>es.js </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="nx">$</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#container&quot;</span><span class="p">).</span><span class="nx">notify</span><span class="p">({</span>
</span><span class='line'>      <span class="nx">speed</span><span class="o">:</span> <span class="mi">500</span><span class="p">,</span>
</span><span class='line'>      <span class="nx">expires</span><span class="o">:</span> <span class="kc">false</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">es</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventSource</span><span class="p">(</span><span class="s1">&#39;/connect&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="nx">es</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">msg</span> <span class="o">=</span> <span class="nx">$</span><span class="p">.</span><span class="nx">parseJSON</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#container&quot;</span><span class="p">).</span><span class="nx">notify</span><span class="p">(</span><span class="s2">&quot;create&quot;</span><span class="p">,</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">title</span><span class="o">:</span> <span class="nx">msg</span><span class="p">.</span><span class="nx">timestamp</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">text</span><span class="o">:</span> <span class="nx">msg</span><span class="p">.</span><span class="nx">notification</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">})</span>
</span></code></pre></td></tr></table></div></figure>


<p>It’s that simple. The EventSource API is minimal and plugging it into a web framework like Sinatra or Node.js is straightforward.</p>

<p>Now, as we submit notifications from the admin page, our receiver pages are updated with time stamped notifications:</p>

<p>Figure 9.20 Pushing Notifications to the Connected Browsers</p>

<p><img class="figure" alt="Figure 9-20" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter9-images/9-20.png&#8221;></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[SXSWi 2013: 'Battle of the HTML5 Hackers' and 'HTML5 Hacks' Book Signing]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2013/03/12/sxswi-2013-battle-of-the-html5-hackers/&#8221;/>
    <updated>2013-03-12T23:55:00-05:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2013/03/12/sxswi-2013-battle-of-the-html5-hackers</id>
    <content type="html"><![CDATA[<p>We had a great turnout for the &lsquo;Battle of the HTML5 Hackers&rsquo; presentation at SXSWi on Tuesday.</p>

<p><img class="imgL300" alt="SXSWi 2013: Battle of the HTML5 Hackers - Jesse Cravens and Jeff Burtoft" src="http://echo 'jessecravens.com' >> source/CNAME/images/sxsw13/sxsw13-crowd.jpg&#8221;></p>

<p>Using our best CDD (Conference Driven Devlopment) techniques, we walked the audience through the creation of <a href="http://nerdclustr.jit.su">Nerdclustr</a>: an HTML5 mobile Application that helps nerds find other like-minded nerds at conferences events.</p>

<p>Using realtime and mapping technolgies, the app visualizes nerd behavior in map pin clusters.</p>

<p><img class="imgR200" alt="Nerdclustr: SXSWi 2013 Ballroom G Austin Convention Center"  src="http://echo 'jessecravens.com' >> source/CNAME/images/sxsw13/sxsw13-app.png&#8221;></p>

<p>Here is a shot of the app in action (Ballroom G in the Austin Convention Center); it performed well during the presentation. Thanks to <a href="https://www.nodejitsu.com/">Nodjitsu</a> for the quality node.js WebSocket service. After a 2-day hackathon to get the app launched, I ran through a number of deployment options, many of which I have used before for Rails applications. <a href="https://www.nodejitsu.com/">Nodjitsu</a> won out in that it actually supported the WebSokcet protocol and made deployment super simple using the jitsu CLI.</p>

<p><img class="imgL200" alt="Jesse Cravens and Jeff Burtoft: SXSWi 2013 - HTML5 Hacks Book Signing"  src="http://echo 'jessecravens.com' >> source/CNAME/images/sxsw13/sxsw13-booksigning.png&#8221;></p>

<p>Nerdclustr source code is available <a href="https://github.com/html5hacks/nerd-clustr">here</a>.</p>

<p>During the book signing, the bookstore informed us there were only 3 copies left. I&rsquo;m not keen to the selection process of books, but I was little surprised at the limited number of technical books. This is certainly a reflection of the SXSWi demographic, and we also tailored our content and presentation style to this audience.</p>

<p>The slide deck is available here:</p>

<script async class="speakerdeck-embed" data-id="c69c92f06d880130bfaa22000a1f8363" data-ratio="1.77777777777778" src="http://echo 'jessecravens.com' >> source/CNAME//speakerdeck.com/assets/embed.js"></script>




<hr>


<p>Stay tuned for our next presentation happening online, through O&#8217;Reilly Webcasts. Join us for <a href="http://www.oreillynet.com/pub/e/2566">&lsquo;Rethinking the Possibilities of Browser-based Apps with HTML5&rsquo;</a> on Wednesday, March 27, 2013 10AM PT.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[HTML5.tx 2013]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2013/02/03/html5-dot-tx-2013/&#8221;/>
    <updated>2013-02-03T23:09:00-06:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2013/02/03/html5-dot-tx-2013</id>
    <content type="html"><![CDATA[<h3>Embedded JavaScript, HTML5 and the Internet of Things</h3>

<iframe width="560" height="315" src="http://www.youtube.com/embed/H00_BGRkBRM" frameborder="0" allowfullscreen></iframe>




<script async class="speakerdeck-embed" data-slide="46" data-id="92b31ab050b501308fcd1231381d555c" data-ratio="1.2994923857868" src="http://echo 'jessecravens.com' >> source/CNAME//speakerdeck.com/assets/embed.js"></script>


<p>I had a great time presenting at HTML5.tx 2013; here is an embed above of the slide deck. I should have the trailr node module in a presentable format soon and I&rsquo;ll tweet its inclusion in NPM. I have a placeholder here: <a href="https://npmjs.org/package/trailr">trailr at npm</a></p>

<p>I also pushed out the ver.1 trailr-admin UI here: <a href="http://trailr-admin.herokuapp.com/dashboard">trailr-admin.herokuapp.com</a></p>

<p>Most of the demos are included in the nodejshacks-emedded repo here: <a href="https://github.com/nodejshacks/nodejshacks-embedded">https://github.com/nodejshacks</a></p>

<p>Very soon, initial documentation will be available at: <a href="http://trailr.io">trailr.io</a></p>

<p><img class="" alt=""  src="http://echo 'jessecravens.com' >> source/CNAME/images/html5tx2013/embedded.JPG&#8221;></p>

<p>Photo credit: Mitch Fincher: <a href="http://mitchfincher.blogspot.com/2013/02/pictures-from-html5tx-2013-in-austin-tx.html">mitchfincher.blogspot.com</a></p>

<h3>HTML5 Canvas View</h3>

<p><img class="" alt=""  src="http://echo 'jessecravens.com' >> source/CNAME/images/html5tx2013/dash.png&#8221;></p>

<h3>Node.js trailr module &ndash; Web Based Edit (Ace Editor) and WebSocket Deploy to Arduino</h3>

<p><img class="" alt=""  src="http://echo 'jessecravens.com' >> source/CNAME/images/html5tx2013/edit.png&#8221;></p>

<p><img class="" alt=""  src="http://echo 'jessecravens.com' >> source/CNAME/images/html5tx2013/embedded2.JPG&#8221;></p>

<p>Photo credit: Mitch Fincher: <a href="http://mitchfincher.blogspot.com/2013/02/pictures-from-html5tx-2013-in-austin-tx.html">mitchfincher.blogspot.com</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Build a Milestone Calendar with IndexedDB and FullCalendar.js]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2013/01/17/build-a-milestone-calendar-with-indexeddb-and-fullcalendar-dot-js/&#8221;/>
    <updated>2013-01-17T08:47:00-06:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2013/01/17/build-a-milestone-calendar-with-indexeddb-and-fullcalendar-dot-js</id>
    <content type="html"><![CDATA[<h4>IndexedDB is a persistent object data store in the browser. Although it is not a full SQL implementation and it is more complex than the unstructured key–value pairs in localStorage, you can use it to define an API that provides the ability to read and write key–value objects as structured JavaScript objects, and an indexing system that facilitates filtering and lookup.</h4>

<p>For this hack we will use IndexedDB to store milestone objects for a calendar application. The UI will provide a simple means to create a new milestone and provide a title, start date, and end date. The calendar will then update to show the contents of the local data store. Figure 6-8 shows the result.</p>

<p>Figure 6-8. FullCalendar.js and IndexedDB</p>

<p><img class="figure" alt="Figure 6-8" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter6-images/6-8.png&#8221;></p>

<p>We need to start by including the markup for the two pieces of the UI: the calendar and the form.
We’ll begin with the form. You may notice that the input fields for the dates include data-date-format attributes. We will use these later for the JavaScript date pickers.</p>

<figure class='code'><figcaption><span>milestone form </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;form>
</span><span class='line'>     &lt;fieldset>
</span><span class='line'>
</span><span class='line'>       &lt;div class="control-group">
</span><span class='line'>         &lt;label class="control-label">Add a Milestone&lt;/label>
</span><span class='line'>         &lt;div class="controls">
</span><span class='line'>           &lt;h2>New Milestone&lt;/h2>
</span><span class='line'>           &lt;input type="text" name="title" value="">
</span><span class='line'>           &lt;input type="text" class="span2" name="start"
</span><span class='line'>             value="07/16/12" data-date-format="mm/dd/yy" id="dp1" >
</span><span class='line'>           &lt;input type="text" class="span2" name="end"
</span><span class='line'>             value="07/17/12"  data-date-format="mm/dd/yy" id="dp2" >
</span><span class='line'>         &lt;/div>
</span><span class='line'>       &lt;/div>
</span><span class='line'>
</span><span class='line'>       &lt;div class="form-actions">
</span><span class='line'>          &lt;button type="submit" class="btn btn-primary">Save&lt;/button>
</span><span class='line'>          &lt;button class="btn">Cancel&lt;/button>
</span><span class='line'>       &lt;/div>
</span><span class='line'>
</span><span class='line'>      &lt;/fieldset>
</span><span class='line'> &lt;/form></span></code></pre></td></tr></table></div></figure>


<p>The calendar is provided by <a href="http://arshaw.com/fullcalendar/">FullCalendar.js</a>, a fantastic jQuery plug-in for generating robust calendars from event sources. The library will generate a calendar from a configuration object and a simple div.</p>

<figure class='code'><figcaption><span>simple div </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;div id='calendar'>&lt;/div></span></code></pre></td></tr></table></div></figure>


<p>And we can’t forget to include a few dependencies:</p>

<figure class='code'><figcaption><span>CSS and JavaScript dependencies </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;link href="../assets/css/datepicker.css" rel="stylesheet">
</span><span class='line'>&lt;link href="../assets/css/fullcalendar.css" rel="stylesheet">
</span><span class='line'>
</span><span class='line'>&lt;script src="http://code.jquery.com/jquery-1.7.1.min.js">&lt;/script>
</span><span class='line'>&lt;script src="../assets/js/bootstrap-datepicker.js">&lt;/script>
</span><span class='line'>&lt;script src="../assets/js/fullcalendar.min.js">&lt;/script></span></code></pre></td></tr></table></div></figure>


<p>To improve the user experience, we will also include date pickers for choosing the dates within the form fields for start and end dates (see Figure 6-9).</p>

<p>Figure 6-9. Date pickers</p>

<p><img class="figure" alt="Figure 6-9" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter6-images/6-9.png&#8221;></p>

<p>To instantiate the date pickers we will include the following toward the beginning of our script:</p>

<figure class='code'><figcaption><span>instantiate the date pickers </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$(function(){
</span><span class='line'>    $('#dp1').datepicker();
</span><span class='line'>    $('#dp2').datepicker();
</span><span class='line'>  });</span></code></pre></td></tr></table></div></figure>


<h3>The Milestone IndexedDB</h3>

<p>Now we will set up a global namespace to hold our code, and set up a public milestones array (within the namespace) to hold our milestones temporarily while we pass them between our database and the FullCalendar API. This should make more sense as you continue to read. While we are at it we will need to normalize our indexedDB variable across all of the vendor-specific properties.</p>

<figure class='code'><figcaption><span>namespace and normalize </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>var html5hacks = {};
</span><span class='line'>
</span><span class='line'>html5hacks.msArray = [];
</span><span class='line'>
</span><span class='line'>var indexedDB = window.indexedDB || window.webkitIndexedDB ||
</span><span class='line'>                window.mozIndexedDB;
</span><span class='line'>
</span><span class='line'>if ('webkitIndexedDB' in window) {
</span><span class='line'>  window.IDBTransaction = window.webkitIDBTransaction;
</span><span class='line'>  window.IDBKeyRange = window.webkitIDBKeyRange;
</span><span class='line'>}
</span><span class='line'>Now we can begin to set up our database:
</span><span class='line'>html5hacks.indexedDB = {};
</span><span class='line'>html5hacks.indexedDB.db = null;
</span><span class='line'>
</span><span class='line'>function init() {
</span><span class='line'>  html5hacks.indexedDB.open();
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>init();</span></code></pre></td></tr></table></div></figure>


<p>This will obviously fail for now, but as you can see the initialization begins by calling the open() method on an html5hacks.indexedDB. So let’s take a closer look at open():</p>

<figure class='code'><figcaption><span>open() </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>html5hacks.indexedDB.open = function() {
</span><span class='line'>
</span><span class='line'>  var request = indexedDB.open("milestones");
</span><span class='line'>
</span><span class='line'>  request.onsuccess = function(e) {
</span><span class='line'>    var v = "1";
</span><span class='line'>    html5hacks.indexedDB.db = e.target.result;
</span><span class='line'>
</span><span class='line'>    var db = html5hacks.indexedDB.db;
</span><span class='line'>
</span><span class='line'>    if (v!= db.version) {
</span><span class='line'>      var setVrequest = db.setVersion(v);
</span><span class='line'>      setVrequest.onerror = html5hacks.indexedDB.onerror;
</span><span class='line'>
</span><span class='line'>      setVrequest.onsuccess = function(e) {
</span><span class='line'>        if(db.objectStoreNames.contains("milestone")) {
</span><span class='line'>          db.deleteObjectStore("milestone");
</span><span class='line'>        }
</span><span class='line'>
</span><span class='line'>        var store = db.createObjectStore("milestone",
</span><span class='line'>          {keyPath: "timeStamp"});
</span><span class='line'>
</span><span class='line'>        html5hacks.indexedDB.init();
</span><span class='line'>      };
</span><span class='line'>    }
</span><span class='line'>    else {
</span><span class='line'>      html5hacks.indexedDB.init();
</span><span class='line'>    }
</span><span class='line'>  };
</span><span class='line'>  request.onerror = html5hacks.indexedDB.onerror;
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>First, we need to open the database and pass a name. If the database successfully opens and a connection is made, the onsuccess() callback will be fired.</p>

<p>Within the onsuccess, we then check for a version and call setVersion() if one does not exist. Then we will call createObjectStore() and pass a unique timestamp within the keypath property.</p>

<p>Finally, we call init() to build the calendar and attach the events present in the database.</p>

<figure class='code'><figcaption><span>onsuccess() </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>html5hacks.indexedDB.init = function() {
</span><span class='line'>
</span><span class='line'>  var db = html5hacks.indexedDB.db;
</span><span class='line'>  var trans = db.transaction(["milestone"], IDBTransaction.READ_WRITE);
</span><span class='line'>  var store = trans.objectStore("milestone");
</span><span class='line'>
</span><span class='line'>  var keyRange = IDBKeyRange.lowerBound(0);
</span><span class='line'>  var cursorRequest = store.openCursor(keyRange);
</span><span class='line'>
</span><span class='line'>  cursorRequest.onsuccess = function(e) {
</span><span class='line'>    var result = e.target.result;
</span><span class='line'>
</span><span class='line'>    if(!result == false){
</span><span class='line'>
</span><span class='line'>        $('#calendar').fullCalendar({
</span><span class='line'>          header: {
</span><span class='line'>            left: 'prev,next today',
</span><span class='line'>            center: 'title',
</span><span class='line'>            right: 'month,agendaWeek,agendaDay'
</span><span class='line'>          },
</span><span class='line'>          weekmode: 'variable',
</span><span class='line'>          height: 400,
</span><span class='line'>          editable: true,
</span><span class='line'>          events: html5hacks.msArray
</span><span class='line'>        });
</span><span class='line'>
</span><span class='line'>      return;
</span><span class='line'>
</span><span class='line'>    }else{
</span><span class='line'>
</span><span class='line'>      console.log("result.value" , result.value);
</span><span class='line'>      buildMilestoneArray(result.value);
</span><span class='line'>      result.continue();
</span><span class='line'>    }
</span><span class='line'>  };
</span><span class='line'>  cursorRequest.onerror = html5hacks.indexedDB.onerror;
</span><span class='line'>};</span></code></pre></td></tr></table></div></figure>


<p>At this point we are poised to retrieve all the data from the database and populate our calendar with milestones.
First, we declare the type of transaction to be a READ_WRITE, set a reference to the datastore, set a keyrange, and define a cursorRequest by calling openCursor and passing in the keyrange. By passing in a 0, we ensure that we retrieve all the values greater than zero. Since our key was a timestamp, this will ensure we retrieve all the records.</p>

<p>Once the onsuccess event is fired, we begin to iterate through the records and push the milestone objects to buildMilestoneArray:</p>

<figure class='code'><figcaption><span>buildMilestoneArray() </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>function buildMilestoneArray(ms) {
</span><span class='line'>  html5hacks.msArray.push(ms);
</span><span class='line'>}
</span><span class='line'>When we reach the last record, we build the calendar by passing a configuration object to fullCalendar() and returning:
</span><span class='line'>        $('#calendar').fullCalendar({
</span><span class='line'>          header: {
</span><span class='line'>            left: 'prev,next today',
</span><span class='line'>            center: 'title',
</span><span class='line'>            right: 'month,agendaWeek,agendaDay'
</span><span class='line'>          },
</span><span class='line'>          weekmode: 'variable',
</span><span class='line'>          height: 400,
</span><span class='line'>          editable: true,
</span><span class='line'>          events: html5hacks.msArray
</span><span class='line'>        });
</span><span class='line'>
</span><span class='line'>      return;</span></code></pre></td></tr></table></div></figure>


<h3>Adding Milestones</h3>

<p>Now that we are initializing and building our calendar, we need to begin adding milestones to the database via the form. First let’s use jQuery to set up our form to pass a serialized data object to addMilestone() on each submission:</p>

<figure class='code'><figcaption><span>form submit </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$('form').submit(function() {
</span><span class='line'>
</span><span class='line'>    var data = $(this).serializeArray();
</span><span class='line'>
</span><span class='line'>    html5hacks.indexedDB.addMilestone(data);
</span><span class='line'>    return false;
</span><span class='line'>  });</span></code></pre></td></tr></table></div></figure>


<p>Now let’s submit a few events and then view them in the Chrome Inspector to ensure they are there (see Figure 6-10).</p>

<p>Figure 6-10. Viewing milestone objects in the Chrome Inspector</p>

<p><img class="figure" alt="Figure 6-10" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter6-images/6-10.png&#8221;></p>

<p>Let’s take a closer look at our addMilestone method:</p>

<figure class='code'><figcaption><span>addMilestone() </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>html5hacks.indexedDB.addMilestone = function(d) {
</span><span class='line'>  var db = html5hacks.indexedDB.db;
</span><span class='line'>  var trans = db.transaction(["milestone"], IDBTransaction.READ_WRITE);
</span><span class='line'>  var store = trans.objectStore("milestone");
</span><span class='line'>
</span><span class='line'>  var data = {
</span><span class='line'>    "title": d[0].value,
</span><span class='line'>    "start": d[1].value,
</span><span class='line'>    "end": d[2].value,
</span><span class='line'>    "timeStamp": new Date().getTime()
</span><span class='line'>  };
</span><span class='line'>
</span><span class='line'>  var request = store.put(data);
</span><span class='line'>
</span><span class='line'>  var dataArr = [data]
</span><span class='line'>  request.onsuccess = function(e) {
</span><span class='line'>    $('#calendar').fullCalendar('addEventSource', dataArr);
</span><span class='line'>  };
</span><span class='line'>
</span><span class='line'>  request.onerror = function(e) {
</span><span class='line'>    console.log("Error Adding: ", e);
</span><span class='line'>  };
</span><span class='line'>};</span></code></pre></td></tr></table></div></figure>


<p>We established our read/write connection in much the same way as our html5hacks.indexedDB.init(), but now, instead of only reading data, we write a data object to the data store each time by calling store.put() and passing it data. On the onsuccess we then can call fullcalendar’s addEventSource() and pass it the data wrapped in an array object. Note that it is necessary to transform the data object into an array since that is what the FullCalendar API expects.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Client/Server 3.0: 6 Ways JavaScript is Revolutionizing the Client/Server Relationship]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2012/11/28/client-server-3-dot-0-6-ways-javascript-is-revolutionizing-the-client-server-relationship/&#8221;/>
    <updated>2012-11-28T10:02:00-06:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2012/11/28/client-server-3-dot-0-6-ways-javascript-is-revolutionizing-the-client-server-relationship</id>
    <content type="html"><![CDATA[<p>Im giving a talk at Devcon 5 &ndash; San Francisco this afternoon: Client/Server 3.0: 6 Ways JavaScript is Revolutionizing the Client/Server Relationship. Here is the other talks on the agenda: <a href="http://www.html5report.com/conference/california/agenda.aspx">Devcon 5 &ndash; San Francisco</a>.</p>

<p>Here is a brief summary:</p>

<h3>1 Device Access Within the Browser</h3>

<p>The client gets smarter.</p>

<p>JavaScript Device APIs continue to evolve, allowing more access to device hardware, services and applications such as the camera, microphone, system sensors, native address books, calendars and native messaging applications.
We will explore examples utilizing GeoLocation API, and Device Orientation.</p>

<h3>2 Client Side Processing w/ Background Threads</h3>

<p>The modern web browser&rsquo;s runtime is a single threaded, event loop. Asynchronous programming models, reactionary systems design actually benefit from this architecture. Maturing interpreters improve performance. Web Workers API enables background threads in the browser, making heavy computations realistic.</p>

<p>So, the client gets more powerful, and becomes an application development evnvironment.
We will explore Web Workers processing heavy computations without blocking the UI for further user interaction.</p>

<h3>3 Device Detection and Descriptors / Adaptive Frameworks</h3>

<p>Responsive Web Design is great, but it often isn&rsquo;t enough for larger applications, and applications that need to reach a highly fragmented device market. Adaptive frameworks use DDRs (Device Description Repositories)</p>

<p>We will explore a framework that mixes the best of Responsive with the best of Adaptive: <a href="https://github.com/jessecravens/responderjs">responderJS</a>.</p>

<h3>4 HTML5 Connectivity Revolution and HTTP 2.0</h3>

<p>Peter Lubbers coined the term, HTML5 Connectivity Revolution, to describe the next level, web network technologies such as: Web Sockets API, XHR2, Event Source and Server Sent Events, SPDY, CORS.</p>

<p>Engage in a demo of <a href="https://github.com/jessecravens/robodeck">robodeck</a>, a Web Socket driven Collaborative presenations framework.</p>

<h3>5 Single Runtime, Shared Syntax &hellip; the right way</h3>

<p>Node.js has enabled the same language, single runtime. But, the paradigms are still quite different. Node streams, inspired by Linux pipes, make IO easy and intuitive. Explore pipe(), pump(), and events in Node streams.</p>

<p>Solutions like Browserify, help bring Node.js libraries and NPM dependency management to the browser. Next up, Domnode, wrapping common, client-side, I/O bound APIs (XHR, SSE, WebRTC, etc.) in Node streams syntax.</p>

<h3>6 Embedded JavaScript</h3>

<p>With Node.js, Angstrom Linux, and cloud document stores like MongoDB, the server is now embedded in the microcontroller client.</p>

<p>We will explore Arduino wrappers, and Node.js running on the Beaglebone from Texas Instruments.</p>

<p>The combination of Linux and JavaScript open worlds of opportunity.</p>

<p>Here is the node.js server used on the Beaglebone in the demo: <a href="https://github.com/jessecravens/beagleserver">beagleserver</a>.
The Johnny Five code is located here: <a href="https://github.com/nodejshacks/nodejshacks-embedded">node-embedded</a></p>

<script async class="speakerdeck-embed" data-slide="4" data-id="086813701bf601302fbe22000a1f8a4e" data-ratio="1.2994923857868" src="http://echo 'jessecravens.com' >> source/CNAME//speakerdeck.com/assets/embed.js"></script>




<iframe width="560" height="315" src="http://www.youtube.com/embed/eahWOUYqr90" frameborder="0" allowfullscreen></iframe>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Configure Amazon S3 for Cross Origin Resourse Sharing to Host a Web Font]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2012/11/18/configure-amazon-s3-for-cross-origin-resourse-sharing-to-host-a-web-font/&#8221;/>
    <updated>2012-11-18T19:42:00-06:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2012/11/18/configure-amazon-s3-for-cross-origin-resourse-sharing-to-host-a-web-font</id>
    <content type="html"><![CDATA[<p>Cross-Origin Resource Sharing (CORS) is a specification that allows applications to
make requests to other domains from within the browser. With CORS you have a secure
and easy-to-implement approach for circumventing the browser’s same origin
policy.</p>

<p>In this hack we will explore hosting a web font on a cloud drive. In order to do so, we
will learn how to configure an Amazon S3 bucket to accept requests from other domains.</p>

<p>If you are not already familiar with web fonts and @font-face, refer to Hack #12.</p>

<p>In the next section I provide a bit more background on Amazon S3 and the same origin
policy, before we get into the details of CORS.</p>

<h3>What Is an Amazon S3 Bucket?</h3>

<p>Amazon S3 (Simple Storage Service) is simply a cloud drive. Files of all kinds can be
stored using this service, but web application developers often use it to store static
assets such as images, JavaScript files, and stylesheets.</p>

<p>For performance improvements, web developers like to employ Content Delivery Networks
(CDNs) to serve their static files. While Amazon S3 is not a CDN in and of itself,
it’s easy to activate it as one by using CloudFront.</p>

<p>A bucket refers to the directory name that you choose to store your static files.
To get started let’s set up an account at Amazon and navigate to the Amazon Management
Console; see Figure 9-21.</p>

<p>Figure 9-21. S3 Management Console</p>

<p><img class="figure" alt="Figure 9-21" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter9-images/9-21.png&#8221;></p>

<p>If we click on Create a Bucket we should see the prompt shown in Figure 9-22.</p>

<p>Figure 9-22. Creating an S3 bucket in the S3 Management Console</p>

<p><img class="figure" alt="Figure 9-22" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter9-images/9-22.png&#8221;></p>

<p>Let’s name the bucket and choose a region (see Figure 9-23). As I stated earlier, you
can choose a region to optimize for latency, minimize costs, or address regulatory
requirements.</p>

<p>Figure 9-23. Naming an S3 bucket in the S3 Management Console</p>

<p><img class="figure" alt="Figure 9-23" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter9-images/9-23.png&#8221;></p>

<p>We will go ahead and name our bucket none other than “html5hacks.” You should now
see an admin screen that shows an empty filesystem (see Figure 9-24).</p>

<p>Figure 9-24. The html5hacks S3 bucket</p>

<p><img class="figure" alt="Figure 9-24" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter9-images/9-24.png&#8221;></p>

<p>Well, that was simple. So why are we doing this? Let’s start with some simple browser
security—something called the same origin policy.</p>

<h3>Same Origin Policy</h3>

<p>As the browser becomes more and more of an application platform, application developers
have compelling reasons to write code that makes requests to other domains
in order to interact directly with the content. Wikipedia defines same origin policy as
follows:</p>

<p>In computing, the same origin policy is an important security concept for a
number of browser-side programming languages, such as JavaScript. The
policy permits scripts running on pages originating from the same site to
access each other’s methods and properties with no specific restrictions,
but prevents access to most methods and properties across pages on different
sites.1</p>

<p>1 <a href="http://en.wikipedia.org/wiki/Same_origin_policy">http://en.wikipedia.org/wiki/Same_origin_policy</a></p>

<p>As stated in Wikipedia’s definition, the same origin policy is a good thing; it protects
the end user from security attacks. But it does cause some challenges for web developers.</p>

<p>This is where CORS comes into the picture. CORS allows developers of remote data
and content to designate which domains (through a whitelist) can interact with their
content.</p>

<h3>Using Web Fonts in Your Application</h3>

<p>There are a number of ways to use a web font within your web pages, such as calling
the @font-face service, bundling the font within your application, hosting the web font
in your own Amazon S3 bucket (more on this later), or converting the file to Base64
and embedding the data inline in a data-uri. By the way, the last technique is similar
to the one outlined in Hack #13.</p>

<p>Each of these techniques has limitations.</p>

<ul>
<li>When calling the @font-face service you are limited to the fonts within the particular
service’s database.</li>
<li>Bundling the font within your application does not make use of HTTP caching, so
your application will continue to download the font file on every page request.
Furthermore, you cannot reuse the font within other applications.</li>
<li>Hosting the font in an Amazon S3 bucket works great, except with Firefox, which
enforces the same origin policy on all resources. So the response from the remote
server will be denied.</li>
<li>Converting the font to Base64 adds additional weight to the stylesheet, and does
not take advantage of caching.</li>
</ul>


<p>An exploration into the different types of web fonts is beyond the scope of this hack,
so I will assume that you have already selected the web font BebasNeue.otf.
You can download free and open fonts from sites such as <a href="http://www.dafont.com.">http://www.dafont.com.</a></p>

<h3>Uploading Your Font to Your Amazon S3 Bucket</h3>

<p>Now, all we have to do is to upload the font onto our filesystem in the cloud (see
Figure 9-25).</p>

<p>Figure 9-25. An uploaded BebasNeue font</p>

<p><img class="figure" alt="Figure 9-25" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter9-images/9-25.png&#8221;></p>

<h3>Adding the Web Font to Your Web Page</h3>

<p>In order to add a web font to our page, we need to add a single stylesheet to an HTML
page.</p>

<p>Here is our page. Let’s call it index.html, and add a <link> tag pointing to our base
stylesheet, styles.css.</p>

<figure class='code'><figcaption><span>geo.html </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;html&gt;</span>
</span><span class='line'>  <span class="nt">&lt;head&gt;</span>
</span><span class='line'>    <span class="nt">&lt;title&gt;</span>S3 - font<span class="nt">&lt;/title&gt;</span>
</span><span class='line'>    <span class="nt">&lt;meta</span> <span class="na">charset=</span><span class="s">&quot;utf-8&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>    <span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">&quot;stylesheet&quot;</span> <span class="na">type=</span><span class="s">&quot;text/css&quot;</span> <span class="na">href=</span><span class="s">&quot;styles.css&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/head&gt;</span>
</span><span class='line'>  <span class="nt">&lt;body&gt;</span>
</span><span class='line'>    <span class="nt">&lt;h1</span> <span class="na">class=</span><span class="s">&quot;test&quot;</span><span class="nt">&gt;</span>HTML5 Hacks<span class="err">&lt;</span>/&gt;
</span><span class='line'>  <span class="nt">&lt;/body&gt;</span>
</span><span class='line'><span class="nt">&lt;/html&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>In our styles.css let’s add the following and point to our uploaded file. Also, let’s assign
the font to our H1 header via the test class name.</p>

<figure class='code'><figcaption><span>style.css </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'><span class="k">@font-face</span> <span class="p">{</span>
</span><span class='line'>  <span class="nt">font-family</span><span class="o">:</span> <span class="nt">BebasNeue</span><span class="o">;</span>
</span><span class='line'>  <span class="nt">src</span><span class="o">:</span> <span class="nt">url</span><span class="o">(</span><span class="s1">&#39;https://s3.amazonaws.com/html5hacks/BebasNeue.otf&#39;</span><span class="o">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nc">.test</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">font-family</span><span class="o">:</span> <span class="s1">&#39;BebasNeue&#39;</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now we’ll open a browser and point to our newly created HTML page. In Opera (see
Figure 9-26), Safari, and Chrome our header tag is being styled correctly.</p>

<p>Figure 9-26. Opera browser showing the BebasNeue font</p>

<p><img class="figure" alt="Figure 9-26" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter9-images/9-26.png&#8221;></p>

<p>But if we view it in Firefox, we are having issues (see Figure 9-27).</p>

<p>Figure 9-27. Firefox browser failing to show the BebasNeue font</p>

<p><img class="figure" alt="Figure 9-27" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter9-images/9-27.png&#8221;></p>

<p>If we examine the request for our font in the Chrome Dev Tools Network tab, we will
see that the response from the server is empty (see Figure 9-28).</p>

<p>Figure 9-28. Firefox browser showing an empty response</p>

<p><img class="figure" alt="Figure 9-28" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter9-images/9-28.png&#8221;></p>

<p>What gives? Well, by default, Firefox will only accept links from the same domain as
the host page. If we want to include fonts from different domains, we need to add an
Access-Control-Allow-Origin header to the font.</p>

<p>So, if you try to serve fonts from any CDN, Firefox will not load them.</p>

<h3>What Is CORS?</h3>

<p>The CORS specification uses the XMLHttpRequest object to send and receive headers
from the originating web page to a server that is properly configured in order to
enable cross-site requests.</p>

<p>The server accepting the request must respond with the
Access-Control-Allow-Origin header with either a wildcard (*) or the correct
origin domain sent by the originating web page as the value. If the value is not included,
the request will fail.</p>

<p>Furthermore, for HTTP methods other than GET or POST, such as PUT, a preflight request
is necessary, in which the browser sends an HTTP OPTIONS request to establish
a handshake with the server before accepting the PUT request.</p>

<p>Fortunately, after enough backlash from the development community, Amazon made
CORS configuration available on Amazon S3 via a very simple XML configuration.</p>

<p>Let’s get started.</p>

<h3>Configuring CORS at Amazon S3</h3>

<p>You should already be at your Amazon Management Console at <a href="http://">http://</a>
console.aws.amazon.com. Click on Properties→Permissions→Edit CORS configuration,
and you should receive a modal prompt.</p>

<p>The configuration can accept up to 100 rule definitions, but for our web font we will
only need a few. For this example we will use the wildcard, but if you are doing this in
production, you should whitelist the domains to prevent others from serving your font
from your S3 account on their own web pages. It wouldn’t be the end of the world, but
it might get costly.</p>

<p>The first rule allows cross-origin GET requests from any origin. The rule also allows all
headers in a preflight OPTIONS request through the
Access-Control-Request-Headers header. In response to any preflight OPTIONS
request, Amazon S3 will return any requested headers.</p>

<p>The second rule allows cross-origin GET requests from all origins. The * wildcard
character refers to all origins.</p>

<figure class='code'><figcaption><span>config.xml </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;CORSConfiguration&gt;</span>
</span><span class='line'><span class="nt">&lt;CORSRule&gt;</span>
</span><span class='line'><span class="nt">&lt;AllowedOrigin&gt;</span>*/AllowedOrigin&gt;
</span><span class='line'><span class="nt">&lt;AllowedMethod&gt;</span>GET<span class="nt">&lt;/AllowedMethod&gt;</span>
</span><span class='line'><span class="nt">&lt;/CORSRule&gt;</span>
</span><span class='line'><span class="nt">&lt;/CORSConfiguration&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>So, let’s add our new configuration to our Editor and save (see Figure 9-29).</p>

<p>Figure 9-29. Configuring CORS in the S3 Management Console</p>

<p><img class="figure" alt="Figure 9-29" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter9-images/9-29.png&#8221;></p>

<p>Now, let’s return to Firefox and reload the page. We should now see the header font
styled with our BebasNeue web font, as shown in Figure 9-30.</p>

<p>Figure 9-30. Firefox browser successfully showing the BebasNeue font</p>

<p><img class="figure" alt="Figure 9-30" src="http://echo 'jessecravens.com' >> source/CNAME/images/chapter9-images/9-30.png&#8221;></p>

<p>There is much more to learn about CORS, most notably, HTTP POST usage with certain
MIME types, and sending cookies and HTTP authentication data with requests if so
requested by the CORS-enabled server. So get out there and starting creating your
own CORS hacks.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Upcoming Talk at Devcon5-Austin: Rapid Prototyping HTML5 Applications with NodeJS]]></title>
    <link href="http://echo 'jessecravens.com' >> source/CNAME/blog/2012/09/25/upcoming-talk-at-devcon5-austin-rapid-prototyping-html5-applications-with-nodejs/&#8221;/>
    <updated>2012-09-25T21:50:00-05:00</updated>
    <id>http://echo &#8216;jessecravens.com&#8217; >> source/CNAME/blog/2012/09/25/upcoming-talk-at-devcon5-austin-rapid-prototyping-html5-applications-with-nodejs</id>
    <content type="html"><![CDATA[<p>I&rsquo;m getting ready for an upcoming talk titled: Rapid Prototyping HTML5 Applications with NodeJS, which I will presenting at <a href="http://www.html5report.com/conference/austin2012/Agenda/Agenda-at-a-glance.aspx">Devcon 5 &ndash; Austin</a>.</p>

<p>Here is a brief summary:</p>

<p>With HTML5, the modern web browser continues to mature as a capable application platform.
The new specifications are broad, impacting nearly every technology associated with modern web development including graphics, connectivity, client-side storage, offline access, graphics, multimedia, and performance.
JavaScript continues to be front and center as the core language. NodeJS extends JavaScript&rsquo;s event loop paradigm to the server, and provides JavaScript engineers with the ability to produce functionality deeper in the software stack. This phenomenon has had an impact on types of software development ranging from full-scale, enterprise, mobile applications to robot hobbyists platforms.
See innovative example solutions and learn why NodeJS is an ideal development platform for the production acceleration of next-generation HTML5 applications.</p>

<p>This is the beginning of a transition for me. With the release of HTML5 Hacks, I&rsquo;m beginning to focus more on my ubiquitous JavaScript content. I&rsquo;m excited, I have a lot to share.</p>

<p>Look for an update with a web based version of the slides.</p>

<script async class="speakerdeck-embed" data-id="507da9caa2a4030002063d67" data-ratio="1.299492385786802" src="http://echo 'jessecravens.com' >> source/CNAME//speakerdeck.com/assets/embed.js"></script>

]]></content>
  </entry>
  
</feed>
