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

  <title><![CDATA[Instructure Tech Blog]]></title>
  <link href="http://instructure.github.io/atom.xml" rel="self"/>
  <link href="http://instructure.github.io/"/>
  <updated>2021-06-02T13:06:34-05:00</updated>
  <id>http://instructure.github.io/</id>
  <author>
    <name><![CDATA[Instructure]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Swift: Just Follow the Types]]></title>
    <link href="http://instructure.github.io/blog/2015/02/05/just-follow-the-types/"/>
    <updated>2015-02-05T14:11:00-06:00</updated>
    <id>http://instructure.github.io/blog/2015/02/05/just-follow-the-types</id>
    <content type="html"><![CDATA[<p>As Mac and iOS craftsmen we&rsquo;ve been given a new tool. In some ways it looks a lot like the old tool, a tool we&rsquo;ve been using for many years now. In many ways it is very different. This tool is, of course, the Swift programming language.</p>

<p>A strict type system is one thing that differentiates Swift from Objective-C.<!-- more --> This type system, along with other related features like generic types and custom operators, has started a movement among developers to adopt some techniques that Swift&rsquo;s predecessor made difficult or impossible. Some of these language features and techniques come from the language Haskell, one of the many languages Chris Lattner <a href="http://nondot.org/sabre/">drew inspiration from in creating Swift</a>.</p>

<p><img class="right half" src="https://farm3.static.flickr.com/2658/4293485922_7474ef04ce.jpg" width="375" height="500" title="An old rusty tool." alt="An old rusty tool."></p>

<p>As I try to learn and adopt these new techniques I feel a bit like a woodworker who&rsquo;s been given a new tool, one with new features that I don&rsquo;t completely understand. One trick I&rsquo;ve learned is that with such a strong type system comes certain affordances.</p>

<p>Let&rsquo;s look at an example.</p>

<p><code>Optional</code> has a method called <code>map</code>. Now if you&rsquo;ve used <code>map</code> functions that are common for collection types you might be able to intuit what this map function does. An <code>Optional</code> isn&rsquo;t an array, however, so it might still be a little confusing. But if you take a moment to inspect the type of <code>map</code> you will see the trail of breadcrumbs.</p>

<figure class='code'><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'>func map&lt;U&gt;(f: (T) -&gt; U) -&gt; U?</span></code></pre></td></tr></table></div></figure>


<p>Here we can see that map takes a single function from <code>(T)-&gt;U</code> as a parameter and returns an <code>U?</code> (which is just nice syntax for <code>Optional&lt;U&gt;</code>) as a result. Remember that <code>T</code> is the generic parameter type of the <code>Optional</code> on which you are calling <code>map</code>. This effectively allows us to take an object wrapped up in an <code>Optional</code> <a href="http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html">context</a> and apply a function to it resulting in an <code>Optional</code> object of the given function&rsquo;s return type.</p>

<p>Higher order functions like <code>map</code> are common in functional programming languages. For example, Haskell defines a function <code>fmap</code> that performs the same operation as <code>Optional.map</code>. Haskell programmers use this function so often that they&rsquo;ve even given it an operator: <code>&lt;$&gt;</code>, and many Swift programmers are <a href="https://github.com/typelift/swiftz">following suit</a> (though, due to some limitations on special characters in Swift, most implementations seem to have settled on <code>&lt;^&gt;</code> for that paricular operation).</p>

<p>When confronted with new symbols and <a href="http://chris.eidhof.nl/posts/json-parsing-in-swift.html">unfamiliar techniques for solving problems</a> in a strictly typed language like Swift, I find it helps to follow the types.</p>

<p>Photo by <a href="https://www.flickr.com/photos/hortulus_aptus/">Seán A. O&#8217;Hara</a>. Licensed under <a href="https://creativecommons.org/licenses/by/2.0/">CC BY 2.0</a>.</p>

<div class="about-box">
  <img src="http://0.gravatar.com/avatar/43f93ddd5058f44ffe579d923945117a" class="avatar" align="left" />
  <p>
    Derrick Hathaway is a Sr. Mobile Engineer at Instructure. He is currently working on making Instructure&#8217;s iOS apps more awesome! <br />
    <a href="https://github.com/derrh">Github</a> and
    <a href="http://twitter.com/derrh">Twitter</a>.
  </p>
</div>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Breaking the Rules: Accessible Dialog Components]]></title>
    <link href="http://instructure.github.io/blog/2014/09/25/accessible-dialogs/"/>
    <updated>2014-09-25T09:00:00-05:00</updated>
    <id>http://instructure.github.io/blog/2014/09/25/accessible-dialogs</id>
    <content type="html"><![CDATA[<p>Turns out, <code>role="dialog"</code> isn&rsquo;t your friend.</p>

<h2>Cursor Modes</h2>

<p>When you first start building accessible websites, you learn quickly
that there are different cursor modes when using Windows screen readers,
<a href="http://tink.co.uk/2014/09/understanding-screen-reader-interaction-modes/">Léonie Watson explains them well here</a>.</p>

<p>Certain element roles, like <code>application</code> and <code>dialog</code> will change the
mode of the cursor. Very often this is not what you want. Yes, It does
allow the developer to implement convenient keyboard events for the
component, but it disables the normal keyboard navigation shortcuts for
screen reader users. For sighted users, that would be a lot like opening
your page up in Internet Explorer 5.5 on a mac.</p>

<!--more-->


<h2>The Problem With ARIA Dialogs</h2>

<p>Unlike other components, dialogs and modals usually just contain regular
content like the rest of the website. They don&rsquo;t need special keyboard
navigation implementations, except for handling the escape key to
request to close it.</p>

<p>When you use <code>role="dialog"</code> the forms/focus cursor mode is activated
and the screen reader user can&rsquo;t interact with the content in the dialog
like they can with the rest of the website. In most cases, this results
in much of the content in the dialog becoming completely inaccessible to
them.</p>

<h2>The Solution</h2>

<p>The solution is to &ldquo;hide&rdquo; everything in the application&mdash;except the
dialog&mdash;from the screen reader. This way the dialog can be navigated
normally and the rest of the app is inaccessible until the dialog closes.</p>

<p>In a nutshell:</p>

<ol>
<li>Don&rsquo;t use <code>role="dialog"</code>, to avoid switching cursor modes.</li>
<li>When a dialog opens, set <code>aria-hidden="true"</code> on the rest of the
page and focus the content of the modal.</li>
<li>When a dialog closes, remove the <code>aria-hidden</code> attribute and return
focus to the element that initiated it.</li>
</ol>


<p>The easiest thing to do is simply wrap your entire website in a
containing element and then just manage <code>aria-hidden</code> on that one
element instead of many.</p>

<p>It would end up looking something like this:</p>

<figure class='code'><figcaption><span></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='html'><span class='line'><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;app&quot;</span><span class="nt">&gt;</span> ... <span class="nt">&lt;/div&gt;</span>
</span><span class='line'><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;dialog&quot;</span><span class="nt">&gt;</span> ... <span class="nt">&lt;/div&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>And when the dialog is open:</p>

<figure class='code'><figcaption><span></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='html'><span class='line'><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;app&quot;</span> <span class="na">aria-hidden=</span><span class="s">&quot;true&quot;</span><span class="nt">&gt;</span> ... <span class="nt">&lt;/div&gt;</span>
</span><span class='line'><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;dialog&quot;</span><span class="nt">&gt;</span> ... <span class="nt">&lt;/div&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<h2>But That&rsquo;s Not The Spec!</h2>

<p>The spec probably needs to change to support dialogs where forms mode
doesn&rsquo;t make sense. We implemented this in order to get Canvas certified
as an accessible web application. The web moves fast and the specs don&rsquo;t
always keep up.</p>

<p>Until the specs catch up, and all the parties involved implement them,
we choose to focus on the experience of our users (oh, right, and
<a href="http://webaim.org/services/certification/">getting certified</a>).</p>

<div class="about-box">
  <img src="http://www.gravatar.com/avatar/749001c9fe6927c4b069a45c2a3d68f7?s=100" class="avatar" align="left" />
  <p>
    Ryan Florence heads up the Web Frameworks team at Instructure where
    they chase both squirrels and JavaScript frameworks, inviting the
    rest of the team to join them. Follow his adventures on 
    <a href="https://github.com/rpflorence">Github</a> and 
    <a href="http://twitter.com/ryanflorence">Twitter</a>.
  </p>
</div>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Balanced Product Management]]></title>
    <link href="http://instructure.github.io/blog/2014/08/04/balanced-product-management/"/>
    <updated>2014-08-04T09:54:00-05:00</updated>
    <id>http://instructure.github.io/blog/2014/08/04/balanced-product-management</id>
    <content type="html"><![CDATA[<p>If you look at job descriptions and blogs about product-y things, there are lots of opinions about what makes a great product manager. They talk about owning strategy, roadmaps, markets, and plans. You&rsquo;re like the CEO of your product and use your über creativity to find the special sauce and make all the decisions. Then everyone will be on board with your vision, singing your praises, and sparkly rainbow unicorns will lead your company down the path to IPO.</p>

<p>However, all of that Being in Charge may actually be counterproductive to the mindset that will make you most successful—Not Being in Charge. The truth is, everyone else&rsquo;s input is far more important than mine.</p>

<!--more-->


<p>&ldquo;But,&rdquo; you say, &ldquo;product is supposed to be the mini-CEO and the vision, right? How can you be the vision if you&rsquo;re not deciding all the things?&rdquo;</p>

<p>Here&rsquo;s the secret—what I want doesn&rsquo;t matter. The only thing that will make us win as a company is making an easier or better way for other people to do what they already do. That means that a good product person works for everyone. Users and buyers of our software (of course), engineers, support, client services, designers, salespeople, QA, executives, marketing—they&rsquo;re are all my boss. What they need comes way before what I want.</p>

<p>The trick is in the balance. A good product person keeps an eye on where the market is going, what users need today, things that are confusing or broken, code that&rsquo;s old and crusty, what&rsquo;s losing sales to competitors, where the terrible UX/UI is, and all the executive initiatives.</p>

<p><img class="right half" src="http://instructure.github.io/images/product_eyes.jpg" width="400" height="400" title="This is the wrong way to do product." alt="Many-eyed monster with OK on its shirt."></p>

<p>However, having all those bosses doesn&rsquo;t mean you just do what they tell you to do. The other side to the balance is knowing enough about everything to be able to prioritize, say “no,” and live with your bosses&#8217; inevitable disapproval.</p>

<p>Bug fixes bore marketing. Sales features add complexity for support. Engineers are sad working in ancient code. Executives need this thing to make money. To top it off, no one&rsquo;s asking for what you know they&rsquo;ll need next year or recognizes the magic in your <a href="http://brandinfluencegroup.com/blog/henry-ford-innovation-and-that-faster-horse-quote-patrick-vlaskovits-harvard-business-review/">new car idea</a>.</p>

<p>Sound difficult? It is. You have to be passionate about supporting everyone and really feel their pain. You have to be patient enough to wait if the time isn&rsquo;t right and spend far more time listening than you do talking. You also have to be okay with very delayed reinforcement. But sometimes, when you get the balance just right, you really do get to be part of making a dent in the world.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Approaching Accessibility Testing]]></title>
    <link href="http://instructure.github.io/blog/2014/06/17/approaching-accessibility-testing/"/>
    <updated>2014-06-17T16:37:00-05:00</updated>
    <id>http://instructure.github.io/blog/2014/06/17/approaching-accessibility-testing</id>
    <content type="html"><![CDATA[<p>When I first started learning about accessibility, I had no idea what I was doing. I am a sighted person, and didn&rsquo;t know if what I was doing was correct. I fed a URL to an online accessibility evaluator, which then told me what elements were missing on the page (ie: an image did not have an alt tag). It wasn&rsquo;t until I met a blind person that I started to understand how people with visual impairments actually use the web. Over the years, I picked up a lot of insight on how to conduct accessibility testing, which I want to share with you.</p>

<p> <!--more--></p>

<p>Before I dive into the &ldquo;tips and tricks&rdquo;, I have to dispell a few myths:</p>

<h2>Accessibility Myths</h2>

<h3>Accessibility only affects blind people</h3>

<p>Blind people are not the only ones affected by inaccessible websites; they affect people with motor impairments, color blindness, or cognitive impairments, amongst others. Accessibility testing is necessary because we as human beings should all have access to the web. If you or your company is not doing accessibility testing, bring it up at the next meeting.</p>

<h3>Assistive technology is super cheap</h3>

<p>Many people rely on screenreading software or a braille display, and it can get very expensive. The license for JAWS, a popular screenreading software, costs anywhere from $895 USD to $1,095 USD, and another couple hundred dollars if you want to buy the upgrade that comes out once each year. Choosing to skip an upgrade may mean that the latest version of your web browser may not work well, or at all. A braille display, which is a device that displays braille using pins that move up and down (a necessity if you are deafblind), can cost thousands of dollars. And this is only for your computer &ndash; you have to pay more money on top of that for your mobile devices. Imagine if you had to pay for all that, and it only worked part of the time. It&rsquo;s like buying a car that only runs on Tuesdays.</p>

<h3>Assistive technology is always up to date</h3>

<p>Technology changes so fast that, when we buy the newest smartphone, it becomes outdated months later. In the same way, assistive technology is often behind new web technologies. Screenreaders can&rsquo;t keep up with the fast pace of web development, which includes new features every other week.</p>

<h3>All screenreaders are the same, I only have to test with one</h3>

<p>Like browsers, not all screenreading software is alike. Mac OS X has a built in screenreader called &ldquo;VoiceOver&rdquo;, which you can enable in the Accessibility section of your System Preferences. It also includes a comprehensive guided tutorial. For Windows, two popular options are JAWS and NVDA. NVDA is free and open source, and is available in many languages. For Linux users, Orca, which is also free and open source, is a great option. The screenreader output can greatly vary; when you navigate to a &ldquo;Close&rdquo; button on a modal window, you might hear &ldquo;Button Close Button&rdquo; from one, but hear &ldquo;Close Button&rdquo; from the other. Talk with your users and see what they are using, and if your budget allows, test with as many screenreaders as you can. At Instructure, we test Canvas using the latest version of VoiceOver and JAWS, and are currently evaluating NVDA.</p>

<h3>Accessibility testing is the worst kind of testing</h3>

<p>Testing of any kind can be painful, whether it be writing unit tests or doing user experience testing. Accessibility testing is also on that list, but realize the more you test, the more aware you will be when writing your code. You will start to look out for things here and there because you had to spend twenty minutes trying to navigate to a submenu in a previous commit.</p>

<h3>I can just throw my website at an accesibility evaluator and call it good</h3>

<p>An evaluator only looks at the structure of your site; it doesn&rsquo;t emulate the user experience. We all know that, sometimes, what looks good on paper doesn&rsquo;t work out in real life. The same goes for an evaluator. It will tell you if your headers are out of order, but it won&rsquo;t tell you if your navigation is terrible because you are inconsistent with what keypress you are using for a certain element. You need actual people to test your site out. Which brings me to my next point&hellip;</p>

<h3>Only blind people can do accessibility testing</h3>

<p>Anyone who learns the software or hardware can do accessibility testing. At Instructure, we have our Quality Assurance (QA) engineers do a lot of the testing, and all of them are sighted. If you have questions and would like to ask someone who is blind, there are a lot of resources out there. For those in the education sector, many universities have a disability resource center &ndash; reach out to the coordinator there, and ask for permission to get feedback. Your city or state may also have a dedicated center. We also have the Internet for a reason; use it!</p>

<h2>Where to start and how to test for accessibility</h2>

<p>If you haven&rsquo;t already, run your site through an evaluator. There are many free accessibility evaluators online, where you feed the URL into an evaluator, and it tells you how accessible the page is. Two popular evaluators are <a href="http://wave.webaim.org/" title="WAVE Evaluator">WAVE</a> and <a href="http://fae.cita.uiuc.edu/" title="FAE Evaluator">FAE</a>. If you use FAE, note that it is evaluating in accordance with the Illlinois Information Technology Accessibility Act. Not all evaluators are running against the same guidelines, so find out what it is evaluating against. Many evaluators will use the <a href="http://www.w3.org/TR/WCAG/" title="W3C Guidelines">W3C Web Content Accessibility Guidelines</a>. The evaluator will show you any errors and provide feedback. Do you have redudant title text? Are your forms labeled? These are items that will be pointed out to you, which you can easily fix.</p>

<p>Once you have your baseline, and fixed the structural elements, it&rsquo;s time to move on to testing with real people. Ask for feedback from your users and see what needs the most attention, and start there. Here are a few of the things we do:</p>

<p>1) On each page we check to see if there are headers, a main landmark, and a complementary landmark (if applicable). We also check for to see if there are any lists, forms, and tables on the page, and use the appropriate screenreader key. Many users navigate using these elements to quickly jump to content on a page. It&rsquo;s hard to scroll through an entire page, so make sure headers and landmarks are available for easy access.</p>

<p>2) We try to use the keyboard as much as possible. Keyboard navigation is critical to many users, especially those with physical disabilities. Not everyone can use a trackpad for gestures, but most everyone has a keyboard.</p>

<p>3) We heavily reference the keyboard layout and shortcuts provided by the screenreader we are using. When I first started accessibility testing, I used the tab key to go through the page. I didn&rsquo;t realize there were screenreader users and keyboard only users. If you are unsure of which keys correspond with which action, look up the keyboard layout for your respective screenreader.</p>

<p>4) We look to see if our elements have consistency; not all of the elements on our pages share the same keypress, even if they look the same visually (which, we are working on). For example, don&rsquo;t have a &ldquo;Submit&rdquo; button that reads as a link on one page, and as a button on another. Make sure your elements are all the same under the hood.</p>

<p>5) With links and buttons, we always make sure a user can read the link/button text and execute the appropriate action. Sometimes it will only read the link text and won&rsquo;t open the link. Don&rsquo;t assume something works just because you can navigate to it.</p>

<p>6) We look at a page from top to bottom, then outline all the elements in a spreadsheet. For example, under &ldquo;main body navigation&rdquo;, I would have &ldquo;Reads Assignment Title&rdquo;, &ldquo;Reads Published Button&rdquo;, and etc. Organizing and writing out all the elements and the location make it much easier for other people to read and follow your work.</p>

<p>What we do at Instructure isn&rsquo;t limited to this list; this is merely a springboard for you to start. We also conduct accessibility audits, and actively work with our clients and other vendors. Instructure is also fortunate to have a dedicated accessibility team in addition to engineers who are passionate about accessibility on each individual core team of Canvas.</p>

<p>Tackling accessibility testing may seem like a daunting task, but start with the steps outlined above. Your changes will start out small, and it may seem insignificant, but realize that every effort you make changes the web to be more accessible. Soon, you will be the one teaching others about what you&rsquo;ve learned, and how to make an accessible product. We at Canvas hope that one day, we&rsquo;ll be reading a blog post from you.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Too big to test: combating test apathy in legacy code]]></title>
    <link href="http://instructure.github.io/blog/2014/05/14/too-big-to-test-combating-test-apathy-in-legacy-code/"/>
    <updated>2014-05-14T10:53:00-05:00</updated>
    <id>http://instructure.github.io/blog/2014/05/14/too-big-to-test-combating-test-apathy-in-legacy-code</id>
    <content type="html"><![CDATA[<p>Writing tests for large Rails apps with lots of dependencies and complicated modeling is, without question, a complete nightmare. We often spend more time wrestling with tests than we do writing code. The end result of writing tests for legacy code is unfortunately predictable: a test suite full of holes, poor coverage, and tests that aren&rsquo;t actually testing the thing you think they are. Bugs begin to pile up, technical debt is avoided like the plague, and quick-fix bandaids are applied instead of addressing the problems head on.</p>

<p>We are then faced with a dilemma: our app has become too big and too complicated to test, and we no longer want to write tests for it because it is so painful. This is unavoidable. No matter how many conference talks we attend that promise to teach us how to writing clean, maintainable code, we&rsquo;re still drowning in a bog of bad. The reality isn&rsquo;t that we&rsquo;re bad developers, it&rsquo;s that we don&rsquo;t dictate our workload, deadlines, or priorities. We have to make sacrifices in our code, which isn&rsquo;t a bad thing until it is. So how do we fix it? How do we take away the pain?</p>

<p>The short answer: it&rsquo;s not easy to fix, and it takes time.</p>

<!--more-->


<h3>Prioritize technical test debt</h3>

<p>There is no sense in prioritizing technical debt if you have technical test debt. No one wants to write tests for a messy test suite, and you can&rsquo;t fix problems in your code if the tests are contributing to them. Start chipping away at test apathy by improving the test writing and running experience. There are a few ways to quickly improve your testing environment.</p>

<p><strong>Clean up your factories and spec helpers</strong></p>

<p>Remove redundant factories or duplicate spec helpers. Helpers with miles of conditionals don&rsquo;t actually <em>help</em> anyone. Consider refactoring any method that takes a hash of options to be more semantically named. Search for factory settings or attributes, or helper methods arguments, you often find yourself using and make them the defaults instead of a passed argument.</p>

<p>If you&rsquo;re using a homegrown factory system instead of a gem like <a href="https://github.com/thoughtbot/factory_girl">FactoryGirl</a>, considering refactoring your factories or completely re-writing them. Lots of bad or unused factories can accumulate when you have many developers working on the same code base.</p>

<p><strong>Using Selenium? Delete your specs</strong></p>

<p><em>&hellip; and re-write them</em>, preferably with a Selenium wrapper, such as <a href="https://github.com/jnicklas/capybara">Capybara</a>. Using a wrapper will also helper clean up your cluttered helper files for these specs.</p>

<p>Selenium specs are a source of constant pain and heartache for developers: they take a long time to run, and they&rsquo;re incredibly complicated. It&rsquo;s a lot of test setup and clicking on stuff for <em>one</em> assertion. In lieu of comprehensive Selenium specs that handle all of your edge cases, improve your unit test coverage (on both the client- and server-side), consider writing end-to-end specs for happy paths, and invest in manual testing where people actually click on things. Simplify your Selenium specs and improve your developers&#8217; happiness by only testing your happy paths and expected error messages.</p>

<p><strong>Organize your spec files properly</strong></p>

<p>Do everyone a favor and fix your nesting. If you&rsquo;re using RSpec, you shouldn&rsquo;t have a <code>describe</code> block with a <code>context</code> that has two more sets of nested <code>context</code>s. If a <code>describe</code> or <code>context</code> block only has one test in it, consider re-organizing to incorporate it with other tests. If you&rsquo;re writing unit tests, use the <code>#my_method_name</code> syntax to group your tests together. Re-write tests that contain multiple assertions: why do you need to assert two things in one test? Assertions that loop through arrays or hashes are sometimes necessary, but they should only be checking one thing, not multiple attributes of your objects.</p>

<p>Lastly, re-organize your file so it is in roughly the same order as your code. The first method in your class shouldn&rsquo;t be the second-to-last thing tested. A little file organization goes a long way when it comes to debugging and adding new tests.</p>

<h3>Use your tools well</h3>

<p>A hammer is not a screwdriver, nor is it a crowbar: don&rsquo;t make your developers be the whole toolbox.</p>

<p><strong>QA Analysts: real humans you need</strong></p>

<p>Your developers are not your users: they&rsquo;re your developers. While it is reasonable to expect a level of familiarity with your software, developers ultimately are not the ones using it on a day-to-day basis. They are not the experts on your software. You need experts, and they&rsquo;re not your developers.</p>

<p>Automation is all fine and dandy, but you can&rsquo;t automate people: we&rsquo;re unpredictable and kind of stupid. The huge value in manual QAs and regression tests are that you can actually test your code against the human element. Your QAs Analysts are neither unpredictable nor stupid, but they can replicate that element of humans more realistically than automated tests can.</p>

<p><strong>Regression tests are not a bandaid</strong></p>

<p>Regression tests aren&rsquo;t just good for finding bugs: they are a tool that can help you spot the holes in your test suite. A bug fix for a regression test shouldn&rsquo;t just be a fix to the code, it should also repair the holes in your tests. Dig through your spec files: is the spec for that bug missing? Is it testing the wrong thing? Is the setup wrong? Fix it.</p>

<p><strong>Don&rsquo;t monkey patch it</strong></p>

<p>Use the gems, libraries, and tools as they are actually intended. Your test suite will rapidly spiral out of control (again) if you find yourself ripping apart your tools.</p>

<h3>Maintenance mode</h3>

<p>Fixing bad tests and cleaning up ugly factories is all well and good, but what happens long term? Maintaining a test suite is just as important as maintaining code. If you walk away from your test suite after putting in so much effort, it will be all:</p>

<p><img src="http://25.media.tumblr.com/b60af898d2636d792de3089108562c91/tumblr_mt0qdlrZMR1siookko1_500.gif" alt="Miley Cyrus: &quot;Don't you every say I just walked away, I will always want you.&quot;" /></p>

<p>Don&rsquo;t wreck your test suite by ignoring it.</p>

<p><strong>Don&rsquo;t be afraid of repeating yourself</strong></p>

<p>Sometimes DRY code is bad code, especially if you&rsquo;re creating unnecessary objects or making redundant database calls in your test setup. Clean up the setup that runs before each test, and make sure you&rsquo;re only creating what you need to.</p>

<p><strong>Abstract after the fact</strong></p>

<p>In the (paraphrased) <a href="https://speakerdeck.com/skmetz/all-the-little-things-rubyonales">words of Sandi Metz</a>: it is better to repeat yourself than to abstract the wrong thing. You don&rsquo;t have the perspective to abstract the right thing at the very beginning of your refactoring and cleaning process. To ensure you&rsquo;re not recreating the problem you&rsquo;re trying to fix, periodically block off time to review spec files for duplicate code that can be extracted. It takes time and hindsight, which is why reviewing spec files periodically is just as important as refactoring legacy code.</p>

<p><strong>Remember that tests are code, too</strong></p>

<p>Consider these two quotes:</p>

<blockquote><p>&ldquo;Ugh, I have to write code. This has robbed me of my will to live.&rdquo;</p></blockquote>

<p><em>No developer, anywhere, ever.</em></p>

<blockquote><p>&ldquo;Ugh, I have to write tests. This has robbed me of my will to live.&rdquo;</p></blockquote>

<p><em>All developers, on a daily basis.</em></p>

<p>Why do we dread writing tests so much?</p>

<p>A lot of developers approach tests as an after-the-fact thing: the code is done, it&rsquo;s time to write tests.</p>

<p>But really, it should be: the code is done now that I&rsquo;ve written my tests.</p>

<p>The virtue of TDD is that you <em>have</em> to write tests. You can&rsquo;t write code unless you&rsquo;ve written tests. This one factor has contributed largely to its success. I&rsquo;m not advocating for or against TDD, I&rsquo;m lobbying for you to consider your tests as an essential part of your code.</p>

<p>If anything, a well-written test just proves that you&rsquo;re right, and who doesn&rsquo;t love being right?</p>

<div class="about-box">
  <a href="http://feministy.io"><img src="https://www.gravatar.com/avatar/c79fa237a028944ad06a4b0a50925120.png" class="avatar" align="left" /></a>
  <p>
    <a href="http://feministy.io" class="author-name" target="_blank">Liz Abinante</a> is an engineer for Instructure and co-leader of the <a href="http://www.meetup.com/Girl-Develop-It-Chicago-IL/" target="_blank">Girl Develop It Chicago chapter</a>. She is infectiously enthusiastic about web development, teaching, learning, and tacos. She enjoys writing and <a href="https://speakerdeck.com/feministy/" target="_blank">speaking</a> about education, diversity, and happiness in engineering. Previously, Liz has worked as a writer, editor, and knitwear designer.
  </p>
</div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ember Tech Talks - April 2014]]></title>
    <link href="http://instructure.github.io/blog/2014/04/28/ember-tech-talks-april-2014/"/>
    <updated>2014-04-28T09:19:00-05:00</updated>
    <id>http://instructure.github.io/blog/2014/04/28/ember-tech-talks-april-2014</id>
    <content type="html"><![CDATA[<p>Each month, geeks from near and far join up at Instructure to teach and learn
about <a href="http://emberjs.com">Ember.js</a>. This month we had 3 amazing presentations
which range from beginner to expert level training.</p>

<h2>Ember Functions, Computed Properties, Observers and More by <a href="https://twitter.com/DericAbel">Deric Abel</a></h2>

<iframe width="586" height="440" src="http://instructure.github.io//www.youtube.com/embed/cIJCTd8qJcQ?rel=0" frameborder="0" allowfullscreen></iframe>


<h2>Binding to Twitter Bootstrap with Ember by <a href="https://github.com/brettv">Brett Valentine</a></h2>

<iframe width="586" height="440" src="http://instructure.github.io//www.youtube.com/embed/Z3-t4tF1OPA?rel=0" frameborder="0" allowfullscreen></iframe>


<p><a href="https://github.com/brettv/ember---bootstrap">Slides</a></p>

<h2>répondez, s&#8217;il vous plaît &ndash; a deep dive into Ember Promise/RSVP by <a href="https://github.com/kingpin2k">Daniel Dunkley</a></h2>

<iframe width="586" height="440" src="http://instructure.github.io//www.youtube.com/embed/8WXgm4_V85E?rel=0" frameborder="0" allowfullscreen></iframe>


<p><a href="https://docs.google.com/presentation/d/1DYjd2BzCrj-no2V2NsqqEfsYlliUEWPf8hCtVVkX0lM/pub?start=false&amp;loop=false&amp;delayms=3000">Slides</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[ImageSweep : drawable management for Android]]></title>
    <link href="http://instructure.github.io/blog/2014/04/21/android-image-sweep/"/>
    <updated>2014-04-21T07:29:00-05:00</updated>
    <id>http://instructure.github.io/blog/2014/04/21/android-image-sweep</id>
    <content type="html"><![CDATA[<p>Software engineering is full of trade-offs: speed/memory usage, features/bugs, etc.
The list goes on and on. The Android team here at Instructure found an interesting trade-off: developer-time versus application size.
As we get new icons/images from our UI/UX team, we have two choices: bundle all of them into the application or add them as they&rsquo;re needed in our project.
The trade-off becomes relatively straight-forward: either we spend time constantly adding images to our project or the user has to deal with their size when they install our application.</p>

<p>At a high-level, the solution is simple: find all the unused drawables in the project and remove them when you build for release.
Historically that&rsquo;s been a tedious and error-prone process, but not anymore.
I&rsquo;m proud to announce a new open-source script from Instructure: <a href="https://github.com/instructure/android-ImageSweep">ImageSweep</a>.
It will run through every file in your project and check for references to drawable resources using regular expressions to check for instances of <em>R.drawable.</em> and <em>@drawable/</em>.
The script will then iterate through the resource folder and delete ALL unused drawable resources.</p>

<p>It&rsquo;s extremely easy to use. Simply run:</p>

<pre><code>    python ImageSweep.py project_src_directory
</code></pre>

<p>where <code>project_src_directory</code> is the relative or absolute file-path where your source code lives.
Make sure the chosen directory contains <em>all</em> of your source code and AndroidManifest.xml, but none of the libraries you&rsquo;ve included. The script auto-determines where the project&rsquo;s resource folder is and libraries can potentially break this detection.</p>

<p>We recently added this script to our release process for <a href="https://play.google.com/store/apps/details?id=com.instructure.candroid">Canvas for Android</a>.
In that project, we were able to delete 2,593 files for a total of 72.37 Mbs freed on disk.
This correlated to a <em>46%</em> size decrease on the apk itself and <em>26%</em> size decrease on the installed application.</p>

<p>To get started, visit the <a href="https://github.com/instructure/android-ImageSweep">project homepage</a>. Take note of the warnings in the README prior to using the script.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Continuous Integration]]></title>
    <link href="http://instructure.github.io/blog/2014/02/24/ci/"/>
    <updated>2014-02-24T11:04:00-06:00</updated>
    <id>http://instructure.github.io/blog/2014/02/24/ci</id>
    <content type="html"><![CDATA[<p>Parallelization, Selenium, AWS, and a CI server are common implementations for agile
shops, and we are no exception. Since I&rsquo;ve been here, maintenance hasn&rsquo;t
been a nightmare, nor has it been a dream. We&rsquo;ve learned a few things
to streamline our maintenance process and would love to share the things
that made our lives easier.</p>

<p>When looking at what was eating up our time, we found the differences
between our CI environment and average developer’s environment was at
the forefront. Most of us at Instructure use Macs, a few of us Windows,
and there are a handful Linux users. Among us, browser choice varies,
but the most popular is Chrome. Engineers develop locally using their
own OS, browser type/version and the Ruby Selenium driver to power
tests. Listed below are a few of the differences we found:</p>

<ol>
<li> AWS images were Ubuntu</li>
<li> Variance in browser versions</li>
<li> Selenium grid uses Java stand alone server VS local specs running using native Ruby driver</li>
<li> Variance in native event capabilities VS Jenkins running exclusively using native events</li>
<li> Parallelization in CI vs single threaded specs in developer’s environment</li>
</ol>


<!-- more -->


<p>We began to strive for consistency between the average dev environment and
the CI environments, where we could, without sacraficing production like implementation.
This helped with mitigating many intermittency issues. During this
process, it simplified the CI upgrade process while edging maintenance
towards dreamland and further from Elm St.</p>

<p>So, what did we do to make this happen? First, all logic for Selenium
driver code was changed from Selenium grid\Java stand-alone server to
the native Ruby Selenium driver. This change immediately resulted in
noticeable stability improvements, and easier resolution for
intermittency creep from tests.</p>

<p>In the past, we had challenges reproducing errors, locally, that our CI
server would throw because of the variance in environments. We spent a
lot of time debugging these errors, and had to create CI environments
that devs could SSH into, to debug the spec failures. This was highly
inefficient, and not consistent with the nature or true purpose of CI.
Making the two environments consistent gave us more time to work on
other things, instead of time-consuming and meaningless failures that were challenging and
intensive to debug. Now we are easily able to (for the most part)
reproduce all errors produced by our CI server.</p>

<p>Along the way, we also found Selenium grid was not the ideal solution for us.
The main reason being the variance in spec outcomes
between dev environments and CI, resulting in too much overhead for
maintenance and upgrades, while also sapping dev time on CI spec
debugging. Many shops use a hardware infrastructure that is distributed
across multiple boxes and the tests are farmed out to them; this is
ideal for Selenium grid. We, however, prefer one big box with
parallelization done internally, reducing the need for a Java stand-alone
server and Selenium grid. Capabilities for the drivers are consumed from
config files written at runtime for different browsers and we have no
need to push each test to a Selenium hub to be farmed out to a worker.
We found this complicated setup offered little reward and brought on
noticeable burden in maintenance and stability while introducing a
variance in spec outcomes.</p>

<p>Making these changes made our lives noticeably easier. When managing
or implementing a CI environment, we believe it&rsquo;s prudent to not only consider your core
tech architecture, but the relationship with your developer&rsquo;s workflow.
Although complex implementations of Selenium grid and multiple browsers can be beneficial,
it may add more complications than are worth it.
We recommend a lean implementation of Selenium, using the driver of the native application
language for tighter integration and better maintenance with more consistency between test runs.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ember Run Loop and TDD]]></title>
    <link href="http://instructure.github.io/blog/2014/01/24/ember-run-loop-and-tdd/"/>
    <updated>2014-01-24T08:58:00-06:00</updated>
    <id>http://instructure.github.io/blog/2014/01/24/ember-run-loop-and-tdd</id>
    <content type="html"><![CDATA[<p>Each month, <a href="http://www.meetup.com/EmberJS-SLC/">nerds unite</a> at the Instructure building to share their knowledge on <a href="http://www.emberjs.com">Ember</a>. This month we had two presentations by a couple of Instructure engineers. Here are the videos and accompanying slides/code.</p>

<h2>Ember Run Loop</h2>

<p>Jason Madsen (<a href="https://twitter.com/jason_madsen">@jason_madsen</a>) discussed the what, why, and how of the Ember Run Loop. Learn how Ember manages the run loop for you, and cases where you will want to manage the run loop. Here&rsquo;s a hint: speed and testing.</p>

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


<p><a href="http://knomedia.github.io/presentation_2014_01_23_ember_run_loop">Slides</a></p>

<h2>Testing Your Ember Application using TDD</h2>

<p>Eric Berry (<a href="https://twitter.com/cavneb">@cavneb</a>) presented on how to &ldquo;Test Drive&rdquo; your Ember applications. Eric starts from scratch and walks through different types of tests that can be written. By the end, you will have a much better understanding of how to test your Ember application.</p>

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


<p><a href="http://cavneb.github.io/presentations-2014.01.23-Ember-Testing">Slides</a> |
<a href="https://github.com/cavneb/presentations-2014.01.23-Ember-Testing/tree/master/ember-app">Code</a></p>

<h2>Nerd with us!</h2>

<p>Feel free to join our monthly meetups (even remotely). The meetings are posted at <a href="http://www.meetup.com/EmberJS-SLC/">http://www.meetup.com/EmberJS-SLC/</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Faster I18n Backend for Ruby Written in C]]></title>
    <link href="http://instructure.github.io/blog/2014/01/07/faster-ruby-i18n-backend-written-in-c/"/>
    <updated>2014-01-07T07:32:00-06:00</updated>
    <id>http://instructure.github.io/blog/2014/01/07/faster-ruby-i18n-backend-written-in-c</id>
    <content type="html"><![CDATA[<p>Every so often, we like to do a hack(fest|stravaganza|nado) here at
Instructure. It&rsquo;s an opportunity for engineers to spend several days
building something cool to improve <a href="https://github.com/instructure/canvas-lms">Canvas</a>.</p>

<p>For our inaugural hackthing back in May, I worked on the problem of having
lots of objects in memory in Ruby 1.9. Ruby uses a mark-and-sweep garbage
collector, so the more Ruby objects you have in memory, the longer each GC
run will take. This can be a significant contributor to slow page loads in
a large Rails app like Canvas.</p>

<!--more-->


<p>At the time, Canvas was localized in 7 languages (we&rsquo;re now up to 15). We
use the excellent <a href="https://github.com/svenfuchs/i18n">I18n gem</a> with a
<a href="https://github.com/instructure/canvas-lms/blob/stable/config/initializers/i18n.rb">few</a>
<a href="https://github.com/instructure/canvas-lms/blob/stable/lib/tasks/i18n.rake">handy</a>
<a href="https://github.com/instructure/canvas-lms/tree/stable/lib/i18n_extraction">extensions</a>
of our own. While I18n&rsquo;s default in-memory backend is plenty fast, it
comes at the cost of having all of those strings in memory. Every new
language you add or feature you implement makes the GC problem even worse.</p>

<p>Because localization strings should be static for the lifetime of a Rails
process, there is no reason the garbage collector needs to know about them
at all. But we still want to keep them in memory for optimal speed.</p>

<p>Enter <a href="https://github.com/instructure/i18nema">I18nema</a>, a fast I18n
backend that unstops the garbage collector and gets everything running
quickly and smoothly :).</p>

<h2>What Is an I18nema?</h2>

<p>At its core, I18nema is a Ruby C extension that moves I18n&rsquo;s translations
out of Ruby-land and into C structs. It also includes a handful of other
optimizations to I18n, leading to some nice all around speedups.</p>

<h2>How Is It Administered?</h2>

<p>In your Gemfile, do</p>

<figure class='code'><figcaption><span></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='ruby'><span class='line'><span class="n">gem</span> <span class="no">RUBY_VERSION</span> <span class="o">&gt;=</span> <span class="s1">&#39;2.0&#39;</span> <span class="p">?</span> <span class="s1">&#39;i18nema&#39;</span> <span class="p">:</span> <span class="s1">&#39;i18nema19&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>and then put something like this in an initializer:</p>

<figure class='code'><figcaption><span></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='ruby'><span class='line'><span class="no">I18n</span><span class="o">.</span><span class="n">backend</span> <span class="o">=</span> <span class="ss">I18nema</span><span class="p">:</span><span class="ss">:Backend</span><span class="o">.</span><span class="n">new</span>
</span></code></pre></td></tr></table></div></figure>


<p>You can still pull in additional I18n features (e.g. <code>I18n::Backend::Fallbacks</code>).
Refer to <a href="https://github.com/instructure/i18nema/blob/master/README.md">the README</a>
for more information.</p>

<h2>How Will It Improve My Quality of Life?</h2>

<h3>More Get-Up-and-Go</h3>

<p>I18nema loads translations into memory much more quickly—<strong>over 4x!</strong>—
making for much faster Rails startup time. While this is just a one time
hit, it&rsquo;s very noticeable when you&rsquo;re waiting on it (e.g. console, specs).
In Canvas, I18nema brings it down to a little over a second (from almost
6).</p>

<h3>Minimal Blockage</h3>

<p>Because there are fewer Ruby objects, the periodic GC runs are
proportionally faster with I18nema. That means faster page loads for your
users.</p>

<p>How much faster is a question of how many translations you have versus how
many other Ruby objects. Applications that are localized in more languages
should see a bigger boost (since the translations make up a bigger share
of the original ObjectSpace).</p>

<p>For example, Canvas is translated into fifteen languages, and I18nema
reduces both (startup) ObjectSpace and GC runtime by <strong>about 15%</strong>. As more
languages are added, that number should only increase.</p>

<p>I18nema also moves I18n&rsquo;s normalized_key_cache into C structs. This key
cache grows over time (it eventually holds a key/value for every
translation key used in the app), so that&rsquo;s another area where I18nema is
nicer on ObjectSpace than vanilla I18n.</p>

<h3>More Pep in Your Step</h3>

<p>I18nema speeds up <code>translate</code> calls, getting the right text to your users
more quickly.</p>

<p>Simple lookups (i.e. no options or interpolation) take a bit <strong>over 15%</strong> less
time.</p>

<p>Lookups with options see slightly bigger gains (<strong>over 20%</strong> less time), in
part due to some speedups on the Ruby side of things (I18n uses
<code>Hash#except</code>, which is quite slow when you have a long list of
arguments).</p>

<h2>Is I18nema Right for Me?</h2>

<p>I18nema is not for everyone.</p>

<p>If you&rsquo;re still on Ruby 1.8, you should not use I18nema. Although I18nema
has been tested on Ruby 1.9, 2.0, and 2.1, it has only been benchmarked
on 1.9. You may find it less effective on 2.1, due to its <a href="http://tmm1.net/ruby21-rgengc/">dramatic GC improvements</a>.</p>

<p>When using I18nema, you should make sure that your translation files are
UTF-8. I18nema cannot be used with <code>.rb</code> translation files (only <code>.yml</code>)</p>

<p>Refer to <a href="https://github.com/instructure/i18nema/blob/master/README.md">the fine print</a>
for more information and benchmarks.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Generating Accessible Colors in JavaScript]]></title>
    <link href="http://instructure.github.io/blog/2013/12/30/generating-accessible-colors-in-javascript/"/>
    <updated>2013-12-30T14:42:00-06:00</updated>
    <id>http://instructure.github.io/blog/2013/12/30/generating-accessible-colors-in-javascript</id>
    <content type="html"><![CDATA[<p>We recently released a major upgrade to Canvas&rsquo;s calendar. Although the primary objective was adding an agenda view and other accessibility tools, we also took the opportunity to update its visual design, including the color coding that links events and calendars. We&rsquo;ve released this new color code generator as a Bower package at <a href="https://github.com/instructure/color-slicer">github/instructure/color-slicer</a>. Here&rsquo;s why we switched.</p>

<!--more-->


<h2>Objectives</h2>

<p>Our old color coding system was pretty simple: we had a list of ten hues, and we assigned them to calendars in order. The drawbacks were that colors would repeat after ten calendars and that the colors used weren&rsquo;t very appealing.</p>

<p> <img src="http://i.imgur.com/6lBEr3V.png" alt="" /></p>

<p>Another system we considered was <a href="https://github.com/instructure/canvas-lms/blob/stable/app/coffeescripts/util/contextColors.coffee">our hash-based color generator</a>, which creates a color based on an object name or ID. This would avoid repetition, but unlucky users could end up with three slightly different shades of green for their three courses.</p>

<p>For the new system, then, we had three goals:</p>

<ul>
<li>Produce colors that look nice and are accessibly readable for text.</li>
<li>Allow an unlimited number of colors without repetition.</li>
<li>Keep colors visually distinct, especially for short lists.</li>
</ul>


<h2>Text colors</h2>

<p>The simplest way to generate bright colors would be use HSV and to vary the hue while using 100% saturation and value. For text on a white background, though, this makes yellows almost invisible:</p>

<p><a href="http://jsfiddle.net/3KX8d/1/"><img src="http://i.imgur.com/kk4ntIE.png" /></a></p>

<p>Instead, we use the <a href="http://en.wikipedia.org/wiki/Lab_color_space">Lab color space</a>, which adjusts for human sensitivity to green, providing a better measurement of lightness and more evenly distributed hues. This not only looks better, but also helps users with limited vision by meeting <a href="http://webaim.org/resources/contrastchecker/">WCAG AA contrast guidelines</a>.</p>

<p><a href="http://jsfiddle.net/G9Qmm/1/"><img src="http://i.imgur.com/V5jstLt.png?1" /></a></p>

<h2>Spacing</h2>

<p>An easy way to space the colors would be to divide the hue circle by the number of calendars. We didn&rsquo;t want all of the colors to change whenever a user added a course, though; we wanted to use the same colors for the first three calendars whether there were three or thirty total. To accomplish this, we <a href="http://jsfiddle.net/UqSS3/6/">progressively divide each gap in half</a>: first we use 0°, then 180°, then 90°, then 270°, then 45°, and so on. This way, your first few calendars are always very visually distinct.</p>

<p>Formally, this is essentially an <a href="http://en.wikipedia.org/wiki/Online_algorithm">online</a> <a href="http://en.wikipedia.org/wiki/Thomson_problem">Thomson problem</a>. We&rsquo;re lucky to only have to solve the one-dimensional version, but the same basic idea could certainly be used to vary hue and value simultaneously if you wanted to generate many distinct colors and didn&rsquo;t care about legibility. The <a href="http://sitemason.vanderbilt.edu/page/hmbADS">spiral point heuristic</a> would probably work well&mdash;we&rsquo;d love to see someone send us a pull request.</p>

<h2>Results</h2>

<p>We&rsquo;re always refining our user experience, but we&rsquo;re happy with the look of our new colors.</p>

<p> <img src="http://i.imgur.com/GLSrwyh.png?1" alt="" /></p>

<p>We&rsquo;ve released <a href="https://github.com/instructure/color-slicer">color-slicer</a> in UMD format under an MIT license, so it should be easy to add to your projects. I hope you&rsquo;ll find it useful. My favorite part of working at Instructure&mdash;better than weekly lunch&mdash;is spending most of my time crafting code that we give back to the community. Let us know what you think.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Facebook React vs. Ember]]></title>
    <link href="http://instructure.github.io/blog/2013/12/17/facebook-react-vs-ember/"/>
    <updated>2013-12-17T08:54:00-06:00</updated>
    <id>http://instructure.github.io/blog/2013/12/17/facebook-react-vs-ember</id>
    <content type="html"><![CDATA[<div class="comment">Edited Jan 13, 2014 with minor changes which allow for testing timeouts in Ember.</div>


<p>We engineers at Instructure love <a href="http://www.emberjs.com">Ember</a>. We also love to learn about other frameworks and know which tools are the best for the job at hand. One of the newer frameworks to come out is React.</p>

<p><a href="http://facebook.github.io/react/">React</a> is Facebook&rsquo;s new JavaScript library for building user interfaces. I&rsquo;m excited to see another player in the game of front-end JS frameworks. When we have so much mind share going to a similar problem, we all win.</p>

<p>On the home page <a href="http://instructure.github.io/images/posts/react-website.png">(screenshot)</a>, there are a few examples of how React can be used. I thought it might be fun to show how each of these can be done using Ember.</p>

<!-- more -->


<h2>A Simple Component</h2>

<p>React components take data and return content which is to be displayed. Here&rsquo;s their example code:</p>

<figure class='code'><figcaption><span>React</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='js'><span class='line'><span class="cm">/** @jsx React.DOM */</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">HelloMessage</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
</span><span class='line'>  <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span><span class="p">{</span><span class="s1">&#39;Hello &#39;</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="o">&lt;</span><span class="err">/div&gt;;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</span><span class='line'><span class="nx">React</span><span class="p">.</span><span class="nx">renderComponent</span><span class="p">(</span><span class="o">&lt;</span><span class="nx">HelloMessage</span> <span class="nx">name</span><span class="o">=</span><span class="s2">&quot;John&quot;</span> <span class="o">/&gt;</span><span class="p">,</span> <span class="nx">mountNode</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Let&rsquo;s build this in Ember. For something as simple as this example, a <a href="http://emberjs.com/guides/templates/writing-helpers/">Handlebars Helper</a> will do the trick.</p>

<figure class='code'><figcaption><span>Ember</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='js'><span class='line'><span class="nx">Ember</span><span class="p">.</span><span class="nx">Handlebars</span><span class="p">.</span><span class="nx">helper</span><span class="p">(</span><span class="s1">&#39;hello-message&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">escaped</span> <span class="o">=</span> <span class="nx">Handlebars</span><span class="p">.</span><span class="nx">Utils</span><span class="p">.</span><span class="nx">escapeExpression</span><span class="p">(</span><span class="nx">name</span><span class="p">);</span>
</span><span class='line'>  <span class="k">return</span> <span class="k">new</span> <span class="nx">Handlebars</span><span class="p">.</span><span class="nx">SafeString</span><span class="p">(</span><span class="s1">&#39;&lt;div&gt;Hello &#39;</span> <span class="o">+</span> <span class="nx">escaped</span> <span class="o">+</span> <span class="s1">&#39;&lt;/div&gt;&#39;</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 class="nx">hello</span><span class="o">-</span><span class="nx">message</span> <span class="s2">&quot;John&quot;</span><span class="p">}}}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Example:</h3>

<p><a class="jsbin-embed" href="http://jsbin.com/ecAJuxE/4/edit?html,js,output">Facebook React vs Ember</a><script src="http://static.jsbin.com/js/embed.js"></script></p>

<h2>A Stateful Component</h2>

<p>The stateful component example on the React page is cool. It tracks the elapsed time on a page (since refresh). Here&rsquo;s their code:</p>

<figure class='code'><figcaption><span>React</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>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="kd">var</span> <span class="nx">Timer</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
</span><span class='line'>  <span class="nx">getInitialState</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">{</span><span class="nx">secondsElapsed</span><span class="o">:</span> <span class="mi">0</span><span class="p">};</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nx">tick</span><span class="o">:</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">setState</span><span class="p">({</span><span class="nx">secondsElapsed</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">secondsElapsed</span> <span class="o">+</span> <span class="mi">1</span><span class="p">});</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nx">componentDidMount</span><span class="o">:</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">interval</span> <span class="o">=</span> <span class="nx">setInterval</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">tick</span><span class="p">,</span> <span class="mi">1000</span><span class="p">);</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nx">componentWillUnmount</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">clearInterval</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">interval</span><span class="p">);</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">React</span><span class="p">.</span><span class="nx">DOM</span><span class="p">.</span><span class="nx">div</span><span class="p">({},</span>
</span><span class='line'>      <span class="s1">&#39;Seconds Elapsed: &#39;</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">secondsElapsed</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>Since we are maintaining state within the component itself, let&rsquo;s build it using an Ember Component.</p>

<figure class='code'><figcaption><span>Ember</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='js'><span class='line'><span class="nx">App</span><span class="p">.</span><span class="nx">TimeOnPageComponent</span> <span class="o">=</span> <span class="nx">Em</span><span class="p">.</span><span class="nx">Component</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
</span><span class='line'>  <span class="nx">secondsViewed</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// Increment the secondsViewed attribute</span>
</span><span class='line'>  <span class="nx">tick</span><span class="o">:</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">incrementProperty</span><span class="p">(</span><span class="s1">&#39;secondsViewed&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">onInterval</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span>
</span><span class='line'>    <span class="nx">Ember</span><span class="p">.</span><span class="nx">run</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">tick</span><span class="p">);</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// Initiates timer when element is rendered</span>
</span><span class='line'>  <span class="nx">startTimer</span><span class="o">:</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">_interval</span> <span class="o">=</span> <span class="nx">setInterval</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">onInterval</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">),</span> <span class="mi">1000</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}.</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;didInsertElement&#39;</span><span class="p">),</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// Ensure that the timer stops when closed</span>
</span><span class='line'>  <span class="nx">clearInterval</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">clearInterval</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_interval</span><span class="p">);</span>
</span><span class='line'>    <span class="k">this</span><span class="p">.</span><span class="nx">_interval</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}.</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;willDestroyElement&#39;</span><span class="p">)</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Example:</h3>

<p><a class="jsbin-embed" href="http://jsbin.com/OPeVeted/6/embed?js,output">Facebook React vs Ember</a><script src="http://static.jsbin.com/js/embed.js"></script></p>

<h2>An Application</h2>

<p>The application example is a simple todo list which has a TodoList class (for rendering content) and a TodoApp class (maintains the state and renders the layout). Here&rsquo;s the code:</p>

<figure class='code'><figcaption><span>React</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>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="cm">/** @jsx React.DOM */</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">TodoList</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
</span><span class='line'>  <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">createItem</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">itemText</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="o">&lt;</span><span class="nx">li</span><span class="o">&gt;</span><span class="p">{</span><span class="nx">itemText</span><span class="p">}</span><span class="o">&lt;</span><span class="err">/li&gt;;</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="k">return</span> <span class="o">&lt;</span><span class="nx">ul</span><span class="o">&gt;</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">items</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">createItem</span><span class="p">)}</span><span class="o">&lt;</span><span class="err">/ul&gt;;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">TodoApp</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
</span><span class='line'>  <span class="nx">getInitialState</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">{</span><span class="nx">items</span><span class="o">:</span> <span class="p">[],</span> <span class="nx">text</span><span class="o">:</span> <span class="s1">&#39;&#39;</span><span class="p">};</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nx">onChange</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="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">({</span><span class="nx">text</span><span class="o">:</span> <span class="nx">e</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">value</span><span class="p">});</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nx">handleSubmit</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="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">nextItems</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">items</span><span class="p">.</span><span class="nx">concat</span><span class="p">([</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">text</span><span class="p">]);</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">nextText</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
</span><span class='line'>    <span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">({</span><span class="nx">items</span><span class="o">:</span> <span class="nx">nextItems</span><span class="p">,</span> <span class="nx">text</span><span class="o">:</span> <span class="nx">nextText</span><span class="p">});</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">(</span>
</span><span class='line'>      <span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span>
</span><span class='line'>        <span class="o">&lt;</span><span class="nx">h3</span><span class="o">&gt;</span><span class="nx">TODO</span><span class="o">&lt;</span><span class="err">/h3&gt;</span>
</span><span class='line'>        <span class="o">&lt;</span><span class="nx">TodoList</span> <span class="nx">items</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">items</span><span class="p">}</span> <span class="o">/&gt;</span>
</span><span class='line'>        <span class="o">&lt;</span><span class="nx">form</span> <span class="nx">onSubmit</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">handleSubmit</span><span class="p">}</span><span class="o">&gt;</span>
</span><span class='line'>          <span class="o">&lt;</span><span class="nx">input</span> <span class="nx">onChange</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">onChange</span><span class="p">}</span> <span class="nx">value</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">text</span><span class="p">}</span> <span class="o">/&gt;</span>
</span><span class='line'>          <span class="o">&lt;</span><span class="nx">button</span><span class="o">&gt;</span><span class="p">{</span><span class="s1">&#39;Add #&#39;</span> <span class="o">+</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">items</span><span class="p">.</span><span class="nx">length</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)}</span><span class="o">&lt;</span><span class="err">/button&gt;</span>
</span><span class='line'>        <span class="o">&lt;</span><span class="err">/form&gt;</span>
</span><span class='line'>      <span class="o">&lt;</span><span class="err">/div&gt;</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><span class='line'><span class="nx">React</span><span class="p">.</span><span class="nx">renderComponent</span><span class="p">(</span><span class="o">&lt;</span><span class="nx">TodoApp</span> <span class="o">/&gt;</span><span class="p">,</span> <span class="nx">mountNode</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>When writing this in Ember, we would use both a controller and a handlebars template. The controller will maintain the state and respond to user interaction and the template will display the form and list.</p>

<figure class='code'><figcaption><span>Ember (controller)</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">App</span><span class="p">.</span><span class="nx">ApplicationController</span> <span class="o">=</span> <span class="nx">Em</span><span class="p">.</span><span class="nx">ArrayController</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
</span><span class='line'>  <span class="nx">content</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">[];</span>
</span><span class='line'>  <span class="p">}.</span><span class="nx">property</span><span class="p">(),</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">btnLabel</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="s2">&quot;Add #&quot;</span> <span class="o">+</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;content.length&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}.</span><span class="nx">property</span><span class="p">(</span><span class="s1">&#39;content.length&#39;</span><span class="p">),</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">actions</span><span class="o">:</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">handleSubmit</span><span class="o">:</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">get</span><span class="p">(</span><span class="s1">&#39;content&#39;</span><span class="p">).</span><span class="nx">pushObject</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;text&#39;</span><span class="p">));</span>
</span><span class='line'>      <span class="k">this</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s1">&#39;text&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">);</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>




<figure class='code'><figcaption><span>Ember (template)</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>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;div&gt;</span>
</span><span class='line'>  <span class="nt">&lt;h3&gt;</span>TODO<span class="nt">&lt;/h3&gt;</span>
</span><span class='line'>  <span class="nt">&lt;ul&gt;</span>
</span><span class='line'>  {{#each content}}
</span><span class='line'>    <span class="nt">&lt;li&gt;</span>{{this}}<span class="nt">&lt;/li&gt;</span>
</span><span class='line'>  {{/each}}
</span><span class='line'>  <span class="nt">&lt;/ul&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="nt">&lt;form</span> <span class="err">{{</span><span class="na">action</span> <span class="err">&quot;</span><span class="na">handleSubmit</span><span class="err">&quot;</span> <span class="na">on=</span><span class="s">&quot;submit&quot;</span><span class="err">}}</span><span class="nt">&gt;</span>
</span><span class='line'>    {{input value=text}}
</span><span class='line'>    <span class="nt">&lt;button</span> <span class="na">type=</span><span class="s">&quot;submit&quot;</span><span class="nt">&gt;</span>{{btnLabel}}<span class="nt">&lt;/button&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/form&gt;</span>
</span><span class='line'><span class="nt">&lt;/div&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Example:</h3>

<p><a class="jsbin-embed" href="http://jsbin.com/OkOLEze/4/embed?html,js,output">Facebook React vs Ember</a><script src="http://static.jsbin.com/js/embed.js"></script></p>

<h2>A Component Using External Plugins</h2>

<p>This example on the React website under <em>A Component Using External Plugins</em> is a great example of encapsulating functionality.</p>

<figure class='code'><figcaption><span>React</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>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="cm">/** @jsx React.DOM */</span>
</span><span class='line'>
</span><span class='line'><span class="kd">var</span> <span class="nx">converter</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Showdown</span><span class="p">.</span><span class="nx">converter</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'><span class="kd">var</span> <span class="nx">MarkdownEditor</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
</span><span class='line'>  <span class="nx">getInitialState</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">{</span><span class="nx">value</span><span class="o">:</span> <span class="s1">&#39;Type some *markdown* here!&#39;</span><span class="p">};</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nx">handleChange</span><span class="o">:</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">setState</span><span class="p">({</span><span class="nx">value</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">refs</span><span class="p">.</span><span class="nx">textarea</span><span class="p">.</span><span class="nx">getDOMNode</span><span class="p">().</span><span class="nx">value</span><span class="p">});</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">(</span>
</span><span class='line'>      <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">&quot;MarkdownEditor&quot;</span><span class="o">&gt;</span>
</span><span class='line'>        <span class="o">&lt;</span><span class="nx">h3</span><span class="o">&gt;</span><span class="nx">Input</span><span class="o">&lt;</span><span class="err">/h3&gt;</span>
</span><span class='line'>        <span class="o">&lt;</span><span class="nx">textarea</span>
</span><span class='line'>          <span class="nx">onChange</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">handleChange</span><span class="p">}</span>
</span><span class='line'>          <span class="nx">ref</span><span class="o">=</span><span class="s2">&quot;textarea&quot;</span>
</span><span class='line'>          <span class="nx">defaultValue</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">value</span><span class="p">}</span> <span class="o">/&gt;</span>
</span><span class='line'>        <span class="o">&lt;</span><span class="nx">h3</span><span class="o">&gt;</span><span class="nx">Output</span><span class="o">&lt;</span><span class="err">/h3&gt;</span>
</span><span class='line'>        <span class="o">&lt;</span><span class="nx">div</span>
</span><span class='line'>          <span class="nx">className</span><span class="o">=</span><span class="s2">&quot;content&quot;</span>
</span><span class='line'>          <span class="nx">dangerouslySetInnerHTML</span><span class="o">=</span><span class="p">{{</span>
</span><span class='line'>            <span class="nx">__html</span><span class="o">:</span> <span class="nx">converter</span><span class="p">.</span><span class="nx">makeHtml</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">value</span><span class="p">)</span>
</span><span class='line'>          <span class="p">}}</span>
</span><span class='line'>        <span class="o">/&gt;</span>
</span><span class='line'>      <span class="o">&lt;</span><span class="err">/div&gt;</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><span class='line'>
</span><span class='line'><span class="nx">React</span><span class="p">.</span><span class="nx">renderComponent</span><span class="p">(</span><span class="o">&lt;</span><span class="nx">MarkdownEditor</span> <span class="o">/&gt;</span><span class="p">,</span> <span class="nx">mountNode</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>The caveat to this example is that it assumes that the <a href="https://github.com/coreyti/showdown">showdown</a> library is already loaded. In our Ember example, note that the library is loaded in the <em>head</em>.</p>

<figure class='code'><figcaption><span>Ember (controller)</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='js'><span class='line'><span class="nx">App</span><span class="p">.</span><span class="nx">ApplicationRoute</span> <span class="o">=</span> <span class="nx">Em</span><span class="p">.</span><span class="nx">Route</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
</span><span class='line'>  <span class="nx">model</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">{</span> <span class="nx">value</span><span class="o">:</span> <span class="s1">&#39;Type some *markdown* here!&#39;</span> <span class="p">};</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</span><span class='line'><span class="nx">Em</span><span class="p">.</span><span class="nx">Handlebars</span><span class="p">.</span><span class="nx">registerBoundHelper</span><span class="p">(</span><span class="s1">&#39;markdown&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">str</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">converter</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Showdown</span><span class="p">.</span><span class="nx">converter</span><span class="p">();</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">html</span> <span class="o">=</span> <span class="nx">converter</span><span class="p">.</span><span class="nx">makeHtml</span><span class="p">(</span><span class="nx">str</span> <span class="o">||</span> <span class="s1">&#39;&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="k">return</span> <span class="k">new</span> <span class="nx">Handlebars</span><span class="p">.</span><span class="nx">SafeString</span><span class="p">(</span><span class="nx">html</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>Ember (template)</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='html'><span class='line'><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;container&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="nt">&lt;h3&gt;</span>Input<span class="nt">&lt;/h3&gt;</span>
</span><span class='line'>  {{textarea value=value class=&quot;form-control&quot;}}
</span><span class='line'>  <span class="nt">&lt;h3&gt;</span>Output<span class="nt">&lt;/h3&gt;</span>
</span><span class='line'>  {{markdown value}}
</span><span class='line'><span class="nt">&lt;/div&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>I added Twitter Bootstrap to this example for cleanliness.</p>

<p><a class="jsbin-embed" href="http://jsbin.com/eyOlOFI/7/embed?js,output">Facebook React vs Ember</a><script src="http://static.jsbin.com/js/embed.js"></script></p>

<p>I haven&rsquo;t spent enough time with React to be able to convert the <a href="http://www.emberjs.com">Ember examples</a> to it, but I would love to see someone do that for a better comparison.</p>

<div class="about-box">
  <a href="http://coderberry.me"><img src="https://en.gravatar.com/userimage/2313670/31b6875622886c41f150245d58acbd0e.jpg?size=100" class="avatar" align="left" /></a>
  <p>
    <a href="http://coderberry.me" class="author-name">Eric Berry</a> is a software engineer at <a href="http://www.instructure.com">Instructure</a> and loves giving back to the community via blog posts and meetups. He was a co-founder of <a href="http://h71028.www7.hp.com/enterprise/cache/504712-0-0-225-121.html">ShareAPhoto, Ltd</a>, a European online photo sharing company which was acquired by Hewlett-Packard in 2006. He was the author of <a href="http://www.amazon.com/Rails-Pocket-Reference-OReilly/dp/0596520700">Rails Pocket Reference</a> (published 2008 – O’Reilly). He spear-headed <a href="http://teachmetocode.com/screencasts/page/9/">TeachMeToCode.com</a>, a popular on-demand screencasting website dedicated to helping others learn how to program.
  </p>
</div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Android Async HTTP Clients: Volley vs Retrofit]]></title>
    <link href="http://instructure.github.io/blog/2013/12/09/volley-vs-retrofit/"/>
    <updated>2013-12-09T13:47:00-06:00</updated>
    <id>http://instructure.github.io/blog/2013/12/09/volley-vs-retrofit</id>
    <content type="html"><![CDATA[<p>We recently released a new version of our mobile app for Android. Although it was a huge improvement from previous installments in terms of features, design, and usability, there was one nagging issue in the back of our minds: speed. There are times when the app isn’t as snappy as we’d like it to be. After some profiling, benchmarks, and common sense, we determined that retrieving data from the API (the networking) was the bottleneck.</p>

<h2>The Old Way: AsyncTasks</h2>

<p>As of the latest version, we use the built-in AsyncTasks to retrieve data from Canvas’ servers. A quick Google search will explain the numerous issues with our approach: no orientation-change support, no ability to cancel network calls, as well as no easy way to make API calls in parallel. With the exception of Froyo and Gingerbread, AsyncTasks (by default) run in a serialized fashion. In a practical sense, this means that only one AsyncTask is running at any given time. Views that require multiple API calls (the DashBoard currently has 7) run extremely slow; sometimes taking multiple seconds to load.</p>

<!-- more -->


<h2>Introducing Volley and Retrofit</h2>

<p>Luckily, there are a few third party libraries that provide support for concurrent background threads, network caching, as well as other features that clean up networking code substantially. The first library that we looked into was <a href="https://android.googlesource.com/platform/frameworks/volley/">Volley</a>, an open-source library written by Google. It’s currently used in AOSP Android as well as most of Google’s first-party applications. The other library we looked into was <a href="http://square.github.io/retrofit/">RetroFit</a>, another open-source library written by Square.</p>

<h2>How We Decided</h2>

<p>The decision to switch the architecture of our networking code was not an easy one to make. The interface with the Canvas API is a substantial part of our application. At the time of writing this blog post, the Canvas for Android project has about 43,000 lines of actual code. Around 3,500 lines of that code are dedicated to interfacing with the Canvas API (setting up API endpoints, etc). JSON parsing comprises of another 7,300 lines of code. That means that more than 25% of our code is dedicated to retrieving/saving data from the Canvas API. That’s just making the API calls and parsing the results. That doesn’t include any AsyncTask code or caching, which we feel should be categorized as networking code as well.</p>

<p>As you can see, if we were going to switch out our networking code, it would have to be for <em>compelling</em> reasons as it’d be a huge refactor. In order to decide if it was worth it, we did a lot of reading about both Volley and Retrofit. We looked at forums, blogposts, example code; we read as much as we could. We learned a lot, but we will try to summarize it the best we can.</p>

<p>From outwards appearances, they are quite similar in usage. They both allow you to provide a “callback”, which is an interface with two methods that you must override: success and failure. One of the methods will be called on the main thread at the completion of the asynchronous network call. The big difference is in how you specify the API endpoint and what you actually get back.</p>

<p>With Volley, you specify the <strong>entire</strong> endpoint dynamically (parameters and all) at the time of making the API call. By default, Volley returns a JSONObject or a JSONArray depending on the type of request.</p>

<p>Retrofit, on the other hand, has you set the base endpoint url for all API calls, then it has you build static interfaces that specify endpoints using Java <em>annotations</em>. You can cleanly and dynamically substitute path-segments, POST/GET variables, etc. into the endpoint at the time of making the API call.  In order to make an API call with RetroFit, you call a method on the interface, pass in any substitutions, and it will return to you a java model object. By default, Retrofit does the JSON parsing automatically using GSON (which is really, really fast) although you can plug in your own JSON parser if you want.  Even though the setup is slightly different, the actual API calls are done in a similar way.</p>

<p>In order to get some performance benchmarks, We wrote a sample application where we could control/simulate real-world API calls that Canvas for Android actually makes. It would also give me a little bit of experience actually using the libraries. To start off with, we wrote a very basic app that allowed me to toggle between an easy API with little JSON parsing and a complex API with a long response. The total number of API calls to make could be changed in the app as well. We also included the exact suite of API calls that the Canvas for Android Dashboard makes for a more real-world test. This benchmark showed me three things: 1) they were both significantly easier to use than AsyncTasks, 2) they both cleaned up the codebase, and 3) they were both a lot faster than what we were currently doing. Obviously the benchmarks fluctuated based upon network conditions; however, they consistently outperformed the way we are currently doing our networking.</p>

<p> <img src="http://i.imgur.com/tIdZkl3.png" alt="" /></p>

<p>In all three tests with varying repeats (1 &ndash; 25 times), Volley was anywhere from 50% to 75% faster. Retrofit clocked in at an impressive 50% to 90% faster than the AsyncTasks, hitting the same endpoint the same number of times. On the <em>Dashboard test suite</em>, this translated into loading/parsing the data several seconds faster. That is a massive real-world difference. In order to make the tests fair, the times for AsyncTasks/Volley included the JSON parsing as Retrofit does it for you automatically.</p>

<p>At this point, we wanted to switch our networking library for performance reasons, but our decision had to take other criteria into consideration. If we were going to spend time refactoring a quarter of our code base, we would have to be a little bit picky. Some of the things we took into account were speed, ease of integration, code cleanup, scalability, and time required to write new API calls.</p>

<h2>RetroFit Wins</h2>

<p>In the end, we decided to go with Retrofit for our application. Not only is it ridiculously fast, but it meshes quite well with our existing architecture. We were able to make a parent <em>Callback Interface</em> that automatically handles the error function, caching, and pagination with little to no effort for our APIs. In order to merge in Retrofit, we have to rename our variables to make our models GSON compliant, write a few simple interfaces, delete functions from the old API, and modify our fragments to not use AsyncTasks. Now that we have a few fragments completely converted, it’s pretty painless. There were some growing pains and issues that we had to overcome, but overall it went smoothly. In the beginning, we ran into a few technical issues/bugs, but Square has a fantastic <a href="https://plus.google.com/communities/109244258569782858265">Google+ community</a> that was able to help us through it. We have successfully converted our entire app to Retrofit. A build that&rsquo;s running solely retrofit can be expected in the Play Store in the coming weeks.</p>

<p>Feel free to ask questions in the comments if you have any.</p>

<h2>Resources:</h2>

<h3>Retrofit:</h3>

<ul>
<li><a href="https://github.com/square/retrofit">Source and Samples</a> (Source and samples)</li>
<li><a href="http://square.github.io/retrofit/">Square Homepage</a></li>
<li><a href="https://plus.google.com/u/0/communities/109244258569782858265">Square Google+ Community</a></li>
</ul>


<h3>Volley:</h3>

<ul>
<li><a href="https://android.googlesource.com/platform/frameworks/volley/">Source</a></li>
<li><a href="https://developers.google.com/live/shows/474338138">Demonstration</a></li>
<li><a href="https://github.com/ogrebgr/android_volley_examples">Github of Examples</a></li>
<li><a href="http://www.technotalkative.com/android-volley-library-example">Usage Example</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Crafting accessible content]]></title>
    <link href="http://instructure.github.io/blog/2013/12/02/crafting-accessible-content/"/>
    <updated>2013-12-02T09:52:00-06:00</updated>
    <id>http://instructure.github.io/blog/2013/12/02/crafting-accessible-content</id>
    <content type="html"><![CDATA[<p>At Instructure, we&rsquo;re moving more and more of our app to the client with technologies like <a href="http://emberjs.com">Ember.js</a>. While it and other JavaScript frameworks have made this transition easier, they&rsquo;ve also introduced new challenges around keeping our content accessible.</p>

<p>The old advice we&rsquo;ve all heard about using semantic markup, headers, and <code>alt</code> attributes on <code>&lt;img /&gt;</code> tags is still true, but it doesn&rsquo;t address how we can best develop accessible content in a rich client application. Despite rumors to the contrary, rich content <em>can</em> be accessible if we pay attention to a few basics.</p>

<!--more-->


<h2>Getting started with accessibility</h2>

<blockquote><p>The Web is fundamentally designed to work for all people, whatever their hardware, software, language, culture, location, or physical or mental ability. When the Web meets this goal, it is accessible to people with a diverse range of hearing, movement, sight, and cognitive ability.</p><footer><strong>W3</strong> <cite><a href='http://www.w3.org/standards/webdesign/accessibility'>www.w3.org/standards/webdesign/&hellip;</a></cite></footer></blockquote>


<p>Let&rsquo;s start with a few definitions:</p>

<ul>
<li><strong>Accessibility</strong>: Web content is accessible when it usable by persons with disabilities. While this includes users of screen readers, it also includes persons with cognitive and other disabilities.</li>
<li><strong>WAI-ARIA</strong>: A suite of technologies designed to make rich Internet applications accessible to users with disabilities.</li>
</ul>


<p>Authoring accessible rich content most often means (1) using WAI-ARIA attributes such as <code>role</code> and <code>aria-expanded</code> to mark-up content in a machine-parseable way; (2) ensuring that all content is keyboard navigable; and (3) managing page focus.</p>

<p>So what does all of this mean when you&rsquo;re developing widgets? Let&rsquo;s take a look at an example of a button set component.</p>

<h2>Building a button set</h2>

<p>We&rsquo;re going to build an accessible <a href="http://getbootstrap.com/components/#btn-groups">button set</a> using Twitter&rsquo;s Bootstrap styles and jQuery.</p>

<p>Our button set is going to work like a filter, so users can only select one button at a time. This means it&rsquo;s like a radio button. Watch how we can use aria roles and attributes to convey that behavior to non-sighted users:</p>

<figure class='code'><figcaption><span></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;div</span> <span class="na">class=</span><span class="s">&quot;btn-group&quot;</span> <span class="na">role=</span><span class="s">&quot;radiogroup&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="nt">&lt;button</span> <span class="na">type=</span><span class="s">&quot;button&quot;</span>
</span><span class='line'>          <span class="na">class=</span><span class="s">&quot;btn btn-default active&quot;</span>
</span><span class='line'>          <span class="na">role=</span><span class="s">&quot;radio&quot;</span>
</span><span class='line'>          <span class="na">aria-checked=</span><span class="s">&quot;true&quot;</span><span class="nt">&gt;</span>Open<span class="nt">&lt;/button&gt;</span>
</span><span class='line'>  <span class="nt">&lt;button</span> <span class="na">type=</span><span class="s">&quot;button&quot;</span>
</span><span class='line'>          <span class="na">class=</span><span class="s">&quot;btn btn-default&quot;</span>
</span><span class='line'>          <span class="na">role=</span><span class="s">&quot;radio&quot;</span>
</span><span class='line'>          <span class="na">aria-checked=</span><span class="s">&quot;false&quot;</span><span class="nt">&gt;</span>Closed<span class="nt">&lt;/button&gt;</span>
</span><span class='line'><span class="nt">&lt;/div&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>First, notice that we didn&rsquo;t change Twitter&rsquo;s recommended button set markup &mdash; we only augmented it with the <code>role</code> attributes and an <code>aria-checked</code> attribute. The <code>role</code> attribute describes the component&rsquo;s behavior to screen readers, and <code>aria-checked</code> attribute notifies users of the current option in the same way that the <code>active</code> class does for sighted users.</p>

<p>Here&rsquo;s the JavaScript to make this happen:</p>

<figure class='code'><figcaption><span></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='javascript'><span class='line'><span class="nx">$</span><span class="p">.</span><span class="nx">fn</span><span class="p">.</span><span class="nx">buttonset</span> <span class="o">=</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="k">this</span><span class="p">).</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;click&#39;</span><span class="p">,</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">$target</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">$target</span><span class="p">.</span><span class="nx">siblings</span><span class="p">()</span>
</span><span class='line'>      <span class="p">.</span><span class="nx">removeClass</span><span class="p">(</span><span class="s1">&#39;active&#39;</span><span class="p">)</span>
</span><span class='line'>      <span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">&#39;aria-checked&#39;</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">$target</span>
</span><span class='line'>      <span class="p">.</span><span class="nx">addClass</span><span class="p">(</span><span class="s1">&#39;active&#39;</span><span class="p">)</span>
</span><span class='line'>      <span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">&#39;aria-checked&#39;</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// usage</span>
</span><span class='line'><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;.btn-group .btn&#39;</span><span class="p">).</span><span class="nx">buttonset</span><span class="p">();</span>
</span></code></pre></td></tr></table></div></figure>


<p>While we&rsquo;re defining this as a jQuery plugin, we could have just as easily made an Ember component, an Angular directive, or a Backbone view.</p>

<p>We&rsquo;ve found that this level is often the best place for dealing with accessibility. By handling accessibility details in our reusable widgets and libraries we can code it once and benefit across our stack. New engineers can immediately start writing accessible code, and all engineers benefit from quick, accessible implementations of common patterns.</p>

<p>In this case, our code is almost all standard jQuery. This solution doesn&rsquo;t require us to manage focus or worry about keyboard navigation because buttons are already in the tab order, but often widget markup will need a <code>tabindex=-1</code> attribute and calls like <code>$('.item').focus()</code> to ensure that screen reader users aren&rsquo;t lost on the page.</p>

<p>Here&rsquo;s our component in action (it&rsquo;s easier to test with a screen reader if you pop out this example into its own page first):</p>

<p><a class="jsbin-embed" href="http://jsbin.com/OBoqALa/1/embed?output">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script></p>

<h2>Testing accessibility</h2>

<p>If you&rsquo;re on a Mac, you already have the software you need to get started testing for accessibility. OSX ships with a screen reader, VoiceOver, that can be enabled in your System Preferences and activated by pressing Cmd-F5.</p>

<p>If you&rsquo;re on Windows, take a look at the free <a href="http://www.nvaccess.org/">NVDA</a> or, if you&rsquo;re doing professional development, the more widely used <a href="http://www.freedomscientific.com/products/fs/jaws-product-page.asp">JAWS</a>.</p>

<p>To ensure that everything we write is accessible, we test all new commits in VoiceOver and JAWS as well as in our supported browsers before merging to master. And while giving accessibility top priority alongside visual fidelity and layout initially slowed us down, we&rsquo;ve long since adjusted and now have  better code and a better product.</p>

<h2>Wrapping up</h2>

<p>Developing with accessibility in mind has been a great experience at Instructure. By starting with an eye to accessibility we&rsquo;ve been able to leverage WAI-ARIA tools to create rich, accessible content in an unobtrusive way.</p>

<h3>Additional resources</h3>

<p>To learn more about accessibility, take a look at the W3&rsquo;s <a href="http://www.w3.org/TR/wai-aria-practices">Authoring Practices</a> document. It covers additional topics like keyboard shortcuts, managing focus, and properly labeling content. The Illinois Center of Information Technology and Web Accessibility also have a great <a href="http://test.cita.uiuc.edu/aria/">collection of accessibility examples</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Hello World!]]></title>
    <link href="http://instructure.github.io/blog/2013/12/02/hello-world/"/>
    <updated>2013-12-02T08:39:00-06:00</updated>
    <id>http://instructure.github.io/blog/2013/12/02/hello-world</id>
    <content type="html"><![CDATA[<p>Welcome to our new blog! Instructure is a technology company. And we have some pretty killer technologists who have opinions. This blog is an outlet for them to talk about stuff.</p>

<p>Feel free to join in the discussion. If you disagree, don&rsquo;t be a wimp—speak up.</p>

<p>Look forward to talking more!</p>

<p>Joel
CTO</p>
]]></content>
  </entry>
  
</feed>
