Sie sind auf Seite 1von 144

appliness

THE FIRST DIGITAL MAGAZINE FOR WEB APPLICATION DEVELOPERS


welcome to appliness. the contributors of this free magazine are all professional and passionate developers. if you want to write a tutorial, showcase your application, contact us on our website appliness.com. we hope that you enjoy reading the 6th issue of this magazine.

(
TUTORIALS INTERVIEW SHOWCASE INTERVIEW

TABLE OF CONTENTS

10 things to know about knockout. JS on day one


by Ryan Niemeyer

javascript types
by Dmitry Baranovskiy

frozen ui and web workers


by Michal Chaize

introduction to javascript unit testing


by Jrn Zaefferer

styling your app with twitter bootstrap


by Holly Schinsky

tame the mobile web beast


by Andre Jay Meissner

apply and arrays: three tricks


by Dr. Alex Rauschmayer

creeps and weirdos in the css spec


by Louis Lazaris

how to write a well structured css - PART 1


by Kianosh Pourian

js design pattern: singleton, composite and facade


by Joe Zimmerman

thoughts on node.js and express


by Raymond Camden

ios safari web apps templates and howtos


by Greg Wilson

infinite timeline scrolling chart


by Mihai Corlan

html5 multimedia troubleshooting


by Ian Devlin

using html templates to generate more than html


by Andrew Trice

vincent hardy - shaping the web


Exclusive interview by Maile Valentine & Michal Chaize

LIBRARY OF THE MONTH

RIVET.JS
by Michal Chaize

HEALTHTAP
by Healthtap

TRICYCLE
Exclusive interview by Maile Valentine

BLEEDING EDGE

MAGAZINE-LIKE LAYOUT FOR THE WEB WITH CSS REGIONS AND EXCLUSIONS
by Christian Cantrell

HELTER SKELTER NEWS

NEWS about html and javascript


by Brian Rinaldi

TEAM

whos behind the magazine

NAVIGATION GUIDE READ

NAVIGATE
GO BACK TO THE LIBRARY MOVE TO THE PREVIOUS ARTICLE DISPLAY THE TABLE OF CONTENTS VISUALLY BROWSE ALL THE ARTICLES

MOVE TO THE NEXT ARTICLE BY A HORIZONTAL SWIPE

READ THROUGH THE ARTICLE BY A VERTICAL SWIPE

appliness

DONT WORRY, BE APPLI

10 Things to Know about Knockout.js on Day One

Knockout.js is a JavaScript library that allows you to declaratively bind elements against model data with two-way updates happening automatically between your UI and model. While Knockout is quite easy to jump into, here are some areas that I feel are commonly misunderstood or overlooked by people that are just getting started with Knockout.

1 - How to set and read observables


Observables are functions that cache their actual value and subscribers internally. You read an observables value by calling it as a function with no arguments and you can set the observable to a new value by passing a single argument to it. var name = ko.observable(Bob); //initialize with a value name(Ted); //set it to a new value alert(name()); //read the value Question: If you need to reference it as a function to read the value, then how come in a data-bind attribute you typically specify just the property name? Answer: Most bindings call ko.utils.unwrapObservable on any values passed to them, which will safely return the value for both observables and non-

ou Playgr

nd

t - JavaScrip - Knockout - Binding

Difficulty
- rookie - intermediate - expert

Todo list

- defered

- observable

- templates

by Ryan Niemeyer

observables. However, if you need to use an observable in an expression inside of your binding string, then you do need to reference it as a function, because it will be evaluated before the binding has access to it. Likewise, in your view model code, you typically need to reference your observables as functions, unless you actually want to pass the observable itself (not the value). <div data-bind=visible: someFlag>...</div> <div data-bind=visible: !someFlag()>...</div>

2 The basic rules of computed observables


By default, the value of a computed observable is determined at the time of creation. However, this behavior can be controlled by creating the computed observable with an object that has a deferEvaluation property set to true. this.total = ko.computed({ read: function() { var result = 0; ko.utils.arrayForEach(this.items(), function(item) { result += item.amount(); }); }, deferEvaluation: true //dont evaluate until someone requests the value }, this); A computed observable will be re-evaluated whenever one of the observables that it accessed in its last evaluation changes. Dependency detection is done each time that the computed observable is evaluated. In the snippet below, if enabled is true, then it will not depend on disabledHelp. However, if enabled becomes false, then it will no longer depend on enabledHelp and will start depending on disabledHelp. //this computed observable will always depend on this.enabled and //will additionally depend on either this.enabledHelp or this.disabledHelp this.helpText = ko.computed({ return this.enabled() ? this.enabledHelp() : this.disabledHelp(); }, this); A computed observable can also accept writes, if a write function is provided. Since, a computed observable doesnt store a value itself, the job of the write function is to intercept the new value and decide how to update other observables, such that its own computed value will be appropriate. this.totalWithTax = ko.computed({ read: function() { return this.total() * (1 + this.taxRate()); }, write: function(newValue) { //do the opposite of the read function and set the total to the correct value this.total(newValue / (1 + this.taxRate())); } }, this);
2/7

3 - An observableArray is just an extended observable


It is helpful to understand that observableArrays are actually just observables. They follow the same rules and have the same features as observables. However, they are also augmented with extra methods to perform basic array operations. These functions perform their action on the underlying array and then notify subscribers that there was a change. This included common operations like pop, push, reverse, shift, sort, splice, and unshift. In addition to the standard array operations, there are several other methods added to handle common tasks. These include remove, removeAll,destroy, destroyAll, replace, and indexOf. //remove an item items.remove(someItem); //remove all items with the name Bob items.remove(function(item) { return item.name === Bob }); //remove all items items.removeAll(); //pass in an array of items to remove items.removeAll(itemsToRemove) //retrieve the index of an item items.indexOf(someItem); //replace an item item.replace(someItem, replaceItem); Note: destroy/destroyAll work like replace/replaceAll, except they mark the items with a_destroy property that is respected by the template and foreach bindings instead of actually removing them from the array.

4 - React to changes using manual subscriptions


Manual subscriptions give you a chance to programmatically react to a specific observable that changes. This is useful in many scenarios such as setting default values, interacting with non-Knockout code, and triggering AJAX requests. You are able to manually subscribe to observables, observableArrays, and computed observables. //trigger an AJAX request to get details when the selection changes this.selectedItem.subscribe(function(newValue) { $.ajax({ url: /getDetails, data: ko.toJSON({ id: newValue.id }), datatype: json, contentType: application/json charset=utf-8, success: function(data) { this.details(data.details); } }); }, this);

3/7

5 Templates are flexible


The template binding is quite flexible. Here are a few ways that you might want to use it: The template binding accepts a data argument that allows you to control the context of the binding. This is handy for simplifying references to nested content. It also accepts an if parameter that helps handle cases when the observable value may be null, so you do not generate errors from binding against properties of an undefined object. <div data-bind=template: { name: nestedTmpl, if: myNestedObject, data: myNestedObject }></div> The template binding also accepts a foreach parameter to loop through items in the array passed to it. If the array is observable and changes, then Knockout efficiently adds or removes DOM nodes appropriately rather than re-rendering the nodes for the entire array. <ul data-bind=template: { name: itemTmpl, foreach: items }></ul> You can even dynamically determine which template should be used to render your data. <ul data-bind=template: { name: getTemplate, foreach: items }></ul> function getTemplate(item) { return item.readOnly() ? viewOnly : editable; }; Finally, there are a number of callbacks supported by the template binding including afterRender,afterAdd, and beforeRemove. These hooks provide you with the affected elements and their associated data allowing you to perform actions like animating items that are being added or removed from an observableArray.

6 - Control-flow bindings are wrappers to the template binding


The control-flow bindings (foreach, if, ifnot, and with) are really wrappers to the template binding. Rather than pulling their content from a named template, they instead save off the children of the element to use as the template each time that a change is detected. These bindings help to simplify your markup and are especially useful in scenarios where you do not need to reuse the template content in other areas of your page. <ul data-bind=foreach: items> <li data-bind=text: name></li> </ul> <div data-bind=if: nestedObject> <div data-bind=text: nestedObject().value </div> <div data-bind=with: nestedObject> <div data-bind=text: value></div> </div>
4/7

Knockout also provides a comment-based syntax that allows you to use these bindings without a parent element. This is particularly useful in scenarios where adding another level is inappropriate, like in a list that contains static and dynamic content. <ul> <li>Static Content</li> <!-- ko foreach: items --> <li data-bind=text: name></li> <!-- /ko --> </ul> <!-- ko if: editable --> <button data-bind=click: save>Save</button> <!-- /ko --> <!-- ko with: nestedObject --> <div data-bind=text: value></div> <!-- /ko -->

7 - Bindings are aware of the current context


Inside of your bindings, Knockout provides a number of useful special variables related to the currentcontext. $data - this is the current data bound at this scope. $root - this is the top-level view model. $parent - this is the data bound one scope level up from the current data. $parents - this is an array of parent view models up to the top-level view model. $parents[0] will be the same as $parent. $parentContext - this provides the context (object containing these special variables) of the parent scope. $index - in the foreach binding, this is an observable representing the current array items index. These special variables make it easy to bind against data or call methods from a higher scope without requiring references to these scopes on your view model itself.

8 - Keeping track of this


Knockout parses the data-bind attribute value on an element and turn it them into a JavaScript object that is used to process the bindings. In the case of event handlers, by the time that Knockout has parsed the binding string, it is dealing with function references that have no implicit value of this. When executing these handlers, such as the ones bound through the event and click bindings, Knockout sets the value of this equal to the current data being bound. This may not always be the appropriate context for your scenario, especially when executing a function that lives in a parent scope. Suppose, our overall view model has a method that deletes an item:
5/7

var ViewModel = function() { this.items = ko.observableArray(); this.deleteItem = function(item) { this.items.remove(item); }; }; If I use this method on a click binding within a foreach loop through an array of items, then this will be set to my individual array items and not the overall view model. <ul data-bind=foreach: items> <li> <span data-bind=text: name></span> <a href=# data-bind=click: $root.deleteItem> x </a> </li> </ul> Conveniently, Knockout also passes the current data as the first argument to any handlers called from the event and click bindings. This means that if we can control the value of this, then we will have both values that we need to perform an action on the array item from its parent. We want the function to execute with this as the parent and receive the array item as the first argument. There are several ways to create your view model in a way that ensures an appropriate value of this when functions are executed. Here are a couple of the most common ways: Knockout does provide an implementation of bind that can be used on any function to create a wrapper that does guarantee the context. In this case, it would look like: this.deleteItem = function(item) { this.items.remove(item); }.bind(this); Alternatively, you can save the correct value of this in a variable and reference it from within the function like: var ViewModel = function() { var self = this; this.items = ko.observableArray(); this.deleteItem = function(item) { self.items.remove(item); }; }; Additionally, manual subscriptions and computed observables do take in a second argument to take care of this for you by controlling the value of this when they are executed. viewmodel.fullName = ko.dependentObservable(function() { return this.firstName() + + this.lastName(); }, viewmodel); viewmodel.gratuityAdded.subscribe(function(newValue) { if (newValue) { this.total(this.total() * 1.15); } }, viewmodel);
6/7

9 - Custom bindings need not be a last resort


There seems to be a slight misconception that custom bindings should only be considered if there is no other way to accomplish the desired functionality with the default bindings. Custom bindings are a powerful extensibility point that can be used in a variety of scenarios and should be considered one of the normal tools that are available to you along with observables, computed observables, and manual subscriptions. Besides helping control custom behavior and/or interacting with 3rd party components, they can also be used to simplify your bindings by encapsulating multiple behaviors. A simple custom binding to start with is one that wraps an existing binding. ko.bindingHandlers.fadeInText = { update: function(element, valueAccessor) { $(element).hide(); ko.bindingHandlers.text.update(element, valueAccessor); $(element).fadeIn(slow); } }; Whenever you find that your view model code is starting to reference DOM elements, then you will likely want to consider isolating this code in a custom binding. Given the element, your data, and the values passed to the binding, you can easily make one or two-way connections between your view model and the UI.

10- ko.toJSON has multiple uses


ko.toJSON is a utility function used to convert objects that include observables to a JSON string. It first creates a clean JavaScript object (you can use ko.toJS to only take it this far), then it callsJSON. stringify on the clean object. Typically, you will be using this technique to package your data for sending back to the server. It can also be very useful for debugging purposes. You can place a pre tag at the bottom of your page and display some or all of your view model using ko.toJSON to get a nicely formatted, live preview of how changes in your UI are affecting the underlying data. No need for console.log calls or alerts. Note that the second and third arguments to ko.toJSON are passed through to JSON.stringify. <hr /> <h2>Debug</h2> <pre data-bind=text: ko.toJSON($root, null, 2)></pre>

ABOUT THIS ARTICLE


Ryan Niemeyer has over 13 years of experience as a technical software tester focusing on .NET and web based technologies. In his spare time, he is active in open source development. As a member of the Knockout.js core team, he focuses primarily on community support, education, and documentation. He also develops a number of Knockout plugins and blogs about his experiences at KnockMeOut.net.

ONLINE RESOURCES His blog about KnockOut http://knockmeout.net


KnockOut.JS official website http://knockoutjs.com/ KnockOut documentation http://knockoutjs.com/documentation/introduction.html

http://knockmeout.net/

@RPNiemeyer

appliness

DONT WORRY, BE APPLI

Javascript types

Dmitry is a Sydney-based web developer, interested in HTML, CSS, JavaScript, XSLT and SVG. Currently he is working at Adobe as Senior Computer Scientist. hes the creator of the javascript library raphael

back in 1997
I like JavaScript. It is a language that is both powerful and flexible, but only if you know how to use it. Once you have mastered the JavaScript language you can build almost anything, and you can do so quickly and interactively. If you think JavaScript is simple or primitive, then you have fallen into a trap. You will find that you have much company in this trap. The so-called JavaScript developers down there may tell you that some other language X is superior. They may even tell you that you would be better off with a system that translates language X into JavaScript. To leave the trap and master JavaScript requires effort and dedication. I know, because back in 1997 I was there. Since then Ive learned the depth and breadth of JavaScript on my own, by studying the official specification. You can learn the complete language as well. If your title includes JavaScript Developer, you should. In this article, I am going to present short JavaScript program fragment and ask you to predict its output. If you are a JavaScript developer, you will find it to be childs play. If you are still learning the language, you may have some trouble and I hope youll read the explanation that follows.

ou Playgr

nd

t - JavaScrip - String - Objects

Difficulty
- rookie - intermediate - expert

Todo list
- learn - read - assign types
by Dmitry Baranovskiy

The following JavaScript code displays an alert box. What will the alert box contain? One link with hyperlink style. //What will the alert box contain? var five = 5; five.three = 3; alert(five + five.three); Skip to the end of this article to learn the correct answer. Heres an explanation of how JavaScript arrives at that answer.

The six types


There are just six types in JavaScript: Object, Number, String, Boolean, Null, and Undefined. All of the types except Object are also called primitive. The type of a JavaScript variable is not declared explicitly, it is inferred by the JavaScript runtime. In this case the type of the variable called five is Number because it has been assigned a Number literal. Objects include arrays, functions, and ordinary objects. Strings include the empty string, . Numbers may be integers or floating point or the special values NaN and Infinity. The last two primitive types are a little unusual: the only value whose type is Null is null, and the only value whose type is Undefined is undefined. Just like many other computer languages, JavaScript will implicitly convert the type of a value to suit the operator that is being applied to the value. Unlike many computer languages, JavaScript is very aggressive about this. For example the result of 5 - 3 is the Number 2 because the minus operator converts both of its operands to Numbers. If an operand cant be converted to a Number, then NaN (Not a Number) is used instead. For example 5 - Fred is implicitly converted to 5 - NaN, which yields NaN. The complete set of rules for implicit type conversions isnt terribly complicated so long as you know what type of operands each operator requires. The Object and String rules that follow state that initially the Object value is converted to a primitive. If the operands type must be a Number, this means that the JavaScript engine calls the objects valueOf() method and if the result is not primitive, then the result is converted to a String with the objects toString() method. If the operands type must be a String, the process begins by calling the objects toString() method, and if its result is not primitive then the valueOf() method is applied to that. In either case, if the result still isnt a primitive, then an exception is thrown.

I WANNA BE A NUMBER...
If the operands type must be a Number but the type of the operands value is: Object: the value is converted to a primtive and if the result is not a Number then one of the following conversions is applied String:
2/4

the String is converted to a Number per the usual JavaScript rules

Boolean: 1 if the value is true, otherwise 0 Null: 0 Undefined: NaN

I WANNA BE A STRING...
If the operands type must be a String but the type of the operands value is: Object: the value is converted to a primitive and if the result is not a String then one of the following conversions is applied. String: the number as a String, e.g. 123 or 12.34 Boolean: true or false Null: null Undefined: undefined

I WANNA BE A boolean...
If the operands type must be a Boolean but the type of the operands is: Object: true Number: false if the value is zero, otherwise true String: false if the value is the empty string, otherwise true Null: false Undefined:
3/4

false

I WANNA BE An object...
If the operands type must be an Object but the type of the operands value is: Number: the value is boxed with a Number object with new Number(value) String: the value is boxed with a String object with new String(value) Boolean: the value is boxed with a Boolean object with new Boolean(value) Null: an exception will be thrown Undefined: an exception will be thrown

back to the example


Now that the type conversion rules are clear, lets return to the example. var five = 5; five.three = 3; alert(five + five.three); As we noted before, the first line creates a variable called five whose type is Number. When the property accessor is applied to the variable five, its type is converted to Object. This is called boxing and it relies on the Number constructor, which produces an Object, not a Number primitive. The second line of the example is equivalent to this: (new Number(five)).three = 3; As you can see, we have not saved a reference to the new Number Object in any variable. After this expression has been evaluated, the Number Object whose three property was set is discarded. The five variable remains unchanged. The third lines five.three expression causes another Number Object to be created. Since the new Object has no three property, the special undefined value is returned. The result is equivalent to this: alert(5 + undefined); The addition operator converts both of its operands to Numbers. In this case undefined is converted to NaN which yields: alert(5 + NaN); And that is why the Alert box in our example just displays NaN.

appliness

DONT WORRY, BE APPLI

frozen ui and web workers

this article is an introduction to web workers. thanks to this api, you can easily run scripts in background threads. if you notice a freeze in the ui of your application, web workers can solve this.

Introduction to web workers


Im always fascinated by the history of Enterprise applications. In the 90s, large accounts developed and deployed client-server applications. The client-side was in charge of a lot of calculations and was able to render advanced graphics. Then the web architectures appeared with languages such as PHP. As it was easier to deploy and maintain web apps compared to client-server apps, a lot of effort has been put into migrating existing applications. Especially applications that needed to be accessed by external users, users beyond the firewall. Because of the poor capabilities of web browsers at this time, most of the calculations were happening on the server-side. The current trend, inspired by the wave of Rich Internet Applications, forces us to leverage the power of JavaScript virtual machines. This is even more true with mobile applications and hybrid architectures where you need to execute business logic heavily on the client-side. Although browser vendors dramatically improved the speed of JavaScript engines, you will find cases where the single-threaded environment of JavaScript hinders the user experience. If you try to parse a large amount of data (a 5000 row XML file for instance) and display an animation on the screen, or present visual feedback during the parsing, it wont be possible as everything happens in a unique thread. The Web Workers specification introduces an API to execute scripts in a separate thread. In this article, well learn how to use web workers and see the benefits.

ou Playgr

nd

Difficulty
- rookie - intermediate - expert

- HTML5 t - JavaScrip - Loops

Todo list
- stress - work - multithread
by Michal Chaize

web animation with adobe edge animate - final sample


The easiest way to feel a freeze in the UI is to create an animation. Adobe Edge is a tool that lets you quickly create stunning web animations. Ive downloaded some cool assets created by http://artcoreillustrations.de/ and put them together in an Edge stage of 300 px by 300 px. Edge generates an HTML file, index.html, that we will extend to use web workers. Here is my final sample. You can see the animation at the top and two buttons. The first one will launch a JavaScript function that runs heavy loops that will freeze the animation for a few seconds. The second button is launching the same calculation using the web worker API. You get the same result, with the same performance, but this time the animation runs smoothly. Youll learn later how to enable this experience and you can access to the source code of this project:

2/5

Stressing the Javascript engine


To stress the JavaScript engine for a few seconds, well run simple calculations into nested loops. Here is the function that will freeze our UI: function stupidLoop(){ var sum = 0; for (var i = 0; i < 10000; i++) { for (var j = 0; j < 20000; j++) { sum++; } } $(#resultTotal).html(Result: + sum); } Edge animations are using jQuery to manipulate the DOM, which explains the last line of code. Well display on the screen a table with two columns in order to compare the launch of this function with and without web workers. Well use Twitter Bootstrap to get a clean UI and nice usable buttons: <head> <link href=css/bootstrap.min.css rel=stylesheet> </head> And declare the table at the end of the HTML page: <table width=300> <tr> <td width=150 bgcolor=#f59b56>DIRECT JS CALL</td> <td width=150 bgcolor=#6db7a5>WITH WEB WORKER</td> </tr> <tr> <td width=150 bgcolor=#f59b56> <a href=# class=btn onClick=stupidLoop()>Launch test</a> </td> <td width=150 bgcolor=#6db7a5> <a href=# class=btn onClick=callWorker()>Launch test</a> </td> </tr> <tr> <td width=150 bgcolor=#f59b56> <div id=resultTotal> (...) </div> </td> <td width=150 bgcolor=#6db7a5> <div id=resultTotalWorker> (...) </div> </td> </tr> <tr>

3/5

<td width=150 bgcolor=#f59b56> <div id=timeTaken> (...) </div> </td> <td width=150 bgcolor=#6db7a5> <div id=timeTakenWorker> (...) </div> </td> </tr> </table>

Calculation time
To measure how long it takes for the JavaScript engine to executes the nested loops, well add some lines of code and display the result in the table: function stupidLoop(){ var start = new Date().getTime(); $(#resultTotal).html(Calculating); var sum = 0; for (var i = 0; i < 10000; i++) { for (var j = 0; j < 20000; j++) { sum++; } } $(#resultTotal).html(Result: + sum); var end = new Date().getTime(); var time = end - start; $(#timeTaken).html(Time: + time + ms); } At this point, you need to understand that web workers wont run your function faster, but it will avoid the freezing of the HTML application.

Creation of the web worker


Creating a web worker is very easy. Just create a new file, workerStupid.js, and add your code. // JavaScript worker self.addEventListener(message, function(event) { var sum = 0; for (var i = 0; i < 10000; i++) { for (var j = 0; j < 20000; j++) {

4/5

sum++; } } self.postMessage(sum); }, false); Notice that its waiting for a message to run the function. Its the classic way to fire a function of a worker from your main HTML page. The worker is also communicating with the main page posting messages: self.postMessage(sum).

CALLING THE worker


In the main HTML page, well call the Worker() constructor: var tempStartTime = 0; var worker = new Worker(workerStupid.js); function callWorker(){ tempStartTime = new Date().getTime(); $(#resultTotalWorker).html(Calculating); worker.postMessage(); } The postMessage in this case is just used to fire a message and run the function inside the message handler. Once the calculation finishes, the worker sends back a message that contains the sum. To handle that message, we just have to declare an event handler on the worker object. worker.addEventListener(message, function (event) { var endWorker = new Date().getTime(); var timeWorker = endWorker - tempStartTime; $(#timeTakenWorker).html(Time: + timeWorker + ms); $(#resultTotalWorker).html(Result: + event.data); }, false); event.data contains the sum as the workers just returns a String. You can also pass JSON data when needed: postMessage({command: start, userId: 2043}); A nice method is terminate() when you need to terminate a running worker (even if its calculation is not complete). worker.terminate();
ONLINE RESOURCES

You can also handle errors using classic ErrorEvents. An on error event handler is called in the worker so that you can start analyzing the error event which implements the ErrorEvent interface. Get the source code of this project on GitHub: https://github.com/michaelchaize/appliness/tree/master/web-workers-animation

appliness

DONT WORRY, BE APPLI

Introduction To JavaScript Unit Testing


discover how to build a testing framework with jorn zaefferer.

testing is good
You probably know that testing is good, but the first hurdle to overcome when trying to write unit tests for client-side code is the lack of any actual units; JavaScript code is written for each page of a website or each module of an application and is closely intermixed with back-end logic and related HTML. In the worst case, the code is completely mixed with HTML, as inline events handlers.

This article was originally published on Smashing Magazine, June 2012.

This is likely the case when no JavaScript library for some DOM abstraction is being used; writing inline event handlers is much easier than using the DOM APIs to bind those events. More and more developers are picking up a library such as jQuery to handle the DOM abstraction, allowing them to move those inline events to distinct scripts, either on the same page or even in a separate JavaScript file. However, putting the code into separate files doesnt mean that it is ready to be tested as a unit.

What is a unit anyway? In the best case, it is a pure function that you can deal with in some way a function that always gives you the same result for a given input. This makes unit testing pretty easy, but most of the time

ou Playgr

nd

- JQuery - QUnit t - JavaScrip

Difficulty
- rookie - intermediate - expert

Todo list

- fix bugs

- refactor - build tests

by Jrn Zaefferer

you need to deal with side effects, which here means DOM manipulations. Its still useful to figure out which units we can structure our code into and to build unit tests accordingly.

Building Unit Tests


With that in mind, we can obviously say that starting with unit testing is much easier when starting something from scratch. But thats not what this article is about. This article is to help you with the harder problem: extracting existing code and testing the important parts, potentially uncovering and fixing bugs in the code. The process of extracting code and putting it into a different form, without modifying its current behavior, is called refactoring. Refactoring is an excellent method of improving the code design of a program; and because any change could actually modify the behaviour of the program, it is safest to do when unit tests are in place. This chicken-and-egg problem means that to add tests to existing code, you have to take the risk of breaking things. So, until you have solid coverage with unit tests, you need to continue manually testing to minimize that risk. That should be enough theory for now. Lets look at a practical example, testing some JavaScript code that is currently mixed in with and connected to a page. The code looks for links with title attributes, using those titles to display when something was posted, as a relative time value, like 5 days ago: //5 DAYS AGO <!DOCTYPE html> <html> <head> <meta http-equiv=Content-Type content=text/html; charset=UTF-8 /> <title>Mangled date examples</title> <script> function prettyDate(time){ var date = new Date(time || ), diff = ((new Date().getTime() - date.getTime()) / 1000), day_diff = Math.floor(diff / 86400); if (isNaN(day_diff) || day_diff < 0 || day_diff >= 31) { return; } return day_diff == 0 && ( diff < 60 && just now || diff < 120 && 1 minute ago || diff < 3600 && Math.floor( diff / 60 ) + minutes ago || diff < 7200 && 1 hour ago || diff < 86400 && Math.floor( diff / 3600 ) + hours ago) || day_diff == 1 && Yesterday || day_diff < 7 && day_diff + days ago || day_diff < 31 && Math.ceil( day_diff / 7 ) + weeks ago; } window.onload = function(){ var links = document.getElementsByTagName(a); for (var i = 0; i < links.length; i++) { if (links[i].title) { var date = prettyDate(links[i].title);

2/18

if (date) { links[i].innerHTML = date; } } } }; </script> </head> <body> <ul> <li class=entry id=post57> <p>blah blah blah</p> <small class=extra> Posted <a href=/2008/01/blah/57/ title=2008-01-28T20:24:17Z>January 28th, 2008</a> by <a href=/john/>John Resig</a> </small> </li> <!-- more list items --> </ul> </body> </html> If you ran that example, youd see a problem: none of the dates get replaced:

The code works, though. It loops through all anchors on the page and checks for a title property on each. If there is one, it passes it to the prettyDate function. If prettyDate returns a result, it updates the innerHTML of the link with the result.

3/18

make things testable


The problem is that for any date older then 31 days, prettyDate just returns undefined (implicitly, with a single return statement), leaving the text of the anchor as is. So, to see whats supposed to happen, we can hardcode a current date: <!DOCTYPE html> <html> <head> <meta http-equiv=Content-Type content=text/html; charset=UTF-8 /> <title>Mangled date examples</title> <script> function prettyDate(now, time){ var date = new Date(time || ), diff = (((new Date(now)).getTime() - date.getTime()) / 1000), day_diff = Math.floor(diff / 86400); if (isNaN(day_diff) || day_diff < 0 || day_diff >= 31) { return; } return day_diff == 0 && ( diff < 60 && just now || diff < 120 && 1 minute ago || diff < 3600 && Math.floor( diff / 60 ) + minutes ago || diff < 7200 && 1 hour ago || diff < 86400 && Math.floor( diff / 3600 ) + hours ago) || day_diff == 1 && Yesterday || day_diff < 7 && day_diff + days ago || day_diff < 31 && Math.ceil( day_diff / 7 ) + weeks ago; } window.onload = function(){ var links = document.getElementsByTagName(a); for (var i = 0; i < links.length; i++) { if (links[i].title) { var date = prettyDate(2008-01-28T22:25:00Z, links[i].title); if (date) { links[i].innerHTML = date; } } } }; </script> </head> <body> <ul> <li class=entry id=post57> <p>blah blah blah</p> <small class=extra> Posted <a href=/2008/01/blah/57/ title=2008-01-28T20:24:17Z>January 28th, 2008</a> by <a href=/john/>John Resig</a> </small> </li>

4/18

<!-- more list items --> <!- January 27th, 2008 January 26th, 2008 January 25th, 2008 January 24th, 2008 January 24th, 2008 January 24th, 2008 December 15th, 2008 --> </ul> </body> </html> Here is the result:

Now, the links should say 2 hours ago, Yesterday and so on. Thats something, but still not an actual testable unit. So, without changing the code further, all we can do is try to test the resulting DOM changes. Even if that did work, any small change to the markup would likely break the test, resulting in a really bad cost-benefit ratio for a test like that.

5/18

Refactoring, Stage 0
Instead, lets refactor the code just enough to have something that we can unit test. We need to make two changes for this to happen: pass the current date to the prettyDate function as an argument, instead of having it just use new Date, and extract the function to a separate file so that we can include the code on a separate page for unit tests. <!DOCTYPE html> <html> <head> <meta http-equiv=Content-Type content=text/html; charset=UTF-8 /> <title>Refactored date examples</title> <script src=prettydate.js></script> <script> window.onload = function() { var links = document.getElementsByTagName(a); for ( var i = 0; i < links.length; i++ ) { if (links[i].title) { var date = prettyDate(2008-01-28T22:25:00Z, links[i].title); if (date) { links[i].innerHTML = date; } } } }; </script> </head> <body> <ul> <li class=entry id=post57> <p>blah blah blah</p> <small class=extra> Posted <a href=/2008/01/blah/57/ title=2008-01-28T20:24:17Z>January 28th, 2008</a> by <a href=/john/>John Resig</a> </small> </li> <!-- more list items --> </ul> </body> </html> Heres the contents of prettydate.js: function prettyDate(now, time){ var date = new Date(time || ), diff = (((new Date(now)).getTime() - date.getTime()) / 1000), day_diff = Math.floor(diff / 86400); if (isNaN(day_diff) || day_diff < 0 || day_diff >= 31) { return; }

6/18

return day_diff == 0 && ( diff < 60 && just now || diff < 120 && 1 minute ago || diff < 3600 && Math.floor( diff / 60 ) + minutes ago || diff < 7200 && 1 hour ago || diff < 86400 && Math.floor( diff / 3600 ) + hours ago) || day_diff == 1 && Yesterday || day_diff < 7 && day_diff + days ago || day_diff < 31 && Math.ceil( day_diff / 7 ) + weeks ago; } Now that we have something to test, lets write some actual unit tests: <!DOCTYPE html> <html> <head> <meta http-equiv=Content-Type content=text/html; charset=UTF-8 /> <title>Refactored date examples</title> <script src=prettydate.js></script> <script> function test(then, expected) { results.total++; var result = prettyDate(2008-01-28T22:25:00Z, then); if (result !== expected) { results.bad++; console.log(Expected + expected + , but was + result); } } var results = { total: 0, bad: 0 }; test(2008/01/28 22:24:30, just now); test(2008/01/28 22:23:30, 1 minute ago); test(2008/01/28 21:23:30, 1 hour ago); test(2008/01/27 22:23:30, Yesterday); test(2008/01/26 22:23:30, 2 days ago); test(2007/01/26 22:23:30, undefined); console.log(Of + results.total + tests, + results.bad + failed, + (results.total - results.bad) + passed.); </script> </head> <body> </body> </html> If you run this sample, here is what the browser console will output: Of 6 tests, 0 failed, 6 passed. This will create an ad-hoc testing framework, using only the console for output. It has no dependencies to the DOM at all, so you could just as well run it in a non-browser JavaScript environment, such as Node.js or Rhino, by extracting the code in the script tag to its own file.

7/18

If a test fails, it will output the expected and actual result for that test. In the end, it will output a test summary with the total, failed and passed number of tests. If all tests have passed, like they should here, you would see the following in the console: Of 6 tests, 0 failed, 6 passed. To see what a failed assertion looks like, we can change something to break it: Expected 2 day ago, but was 2 days ago. Of 6 tests, 1 failed, 5 passed. While this ad-hoc approach is interesting as a proof of concept (you really can write a test runner in just a few lines of code), its much more practical to use an existing unit testing framework that provides better output and more infrastructure for writing and organizing tests.

The QUnit JavaScript Test Suite


The choice of framework is mostly a matter of taste. For the rest of this article, well use QUnit (pronounced q-unit), because its style of describing tests is close to that of our ad-hoc test framework. <!DOCTYPE html> <html> <head> <meta http-equiv=Content-Type content=text/html; charset=UTF-8 /> <title>Refactored date examples</title> <link rel=stylesheet href=qunit.css /> <script src=qunit.js></script> <script src=prettydate.js></script>

<script> test(prettydate basics, function() { var now = 2008/01/28 22:25:00; equal(prettyDate(now, 2008/01/28 22:24:30), equal(prettyDate(now, 2008/01/28 22:23:30), equal(prettyDate(now, 2008/01/28 21:23:30), equal(prettyDate(now, 2008/01/27 22:23:30), equal(prettyDate(now, 2008/01/26 22:23:30), equal(prettyDate(now, 2007/01/26 22:23:30), }); </script> </head> <body> <div id=qunit></div> </body> </html> Now, here is the result:

just now); 1 minute ago); 1 hour ago); Yesterday); 2 days ago); undefined);

8/18

Three sections are worth a closer look here. Along with the usual HTML boilerplate, we have three included files: two files for QUnit (qunit.css and qunit.js) and the previous prettydate.js. Then, theres another script block with the actual tests. The test method is called once, passing a string as the first argument (naming the test) and passing a function as the second argument (which will run the actual code for this test). This code then defines the now variable, which gets reused below, then calls the equal method a few times with varying arguments. The equal method is one of several assertions that QUnit provides. The first argument is the result of a call to prettyDate, with the now variable as the first argument and a date string as the second. The second argument to equal is the expected result. If the two arguments to equal are the same value, then the assertion will pass; otherwise, it will fail. Finally, in the body element is some QUnit-specific markup. These elements are optional. If present, QUnit will use them to output the test results. The result is this:

9/18

With a failed test, the result would look something like this:

Because the test contains a failing assertion, QUnit doesnt collapse the results for that test, and we can see immediately what went wrong. Along with the output of the expected and actual values, we get a diff between the two, which can be useful for comparing larger strings. Here, its pretty obvious what went wrong.

Refactoring, Stage 1
The assertions are currently somewhat incomplete because we arent yet testing the n weeks ago variant. Before adding it, we should consider refactoring the test code. Currently, we are calling prettyDate for each assertion and passing the now argument. We could easily refactor this into a custom assertion method: test(prettydate basics, function() { function date(then, expected) { equal(prettyDate(2008/01/28 22:25:00, then), expected); } date(2008/01/28 22:24:30, just now); date(2008/01/28 22:23:30, 1 minute ago); date(2008/01/28 21:23:30, 1 hour ago); date(2008/01/27 22:23:30, Yesterday); date(2008/01/26 22:23:30, 2 days ago);

10/18

date(2007/01/26 22:23:30, undefined); });

Here weve extracted the call to prettyDate into the date function, inlining the now variable into the function. We end up with just the relevant data for each assertion, making it easier to read, while the underlying abstraction remains pretty obvious.

Testing The DOM manipulation


Now that the prettyDate function is tested well enough, lets shift our focus back to the initial example. Along with the prettyDate function, it also selected some DOM elements and updated them, within the window load event handler. Applying the same principles as before, we should be able to refactor that code and test it. In addition, well introduce a module for these two functions, to avoid cluttering the global namespace and to be able to give these individual functions more meaningful names. <!DOCTYPE html> <html> <head> <meta http-equiv=Content-Type content=text/html; charset=UTF-8 /> <title>Refactored date examples</title> <link rel=stylesheet href=qunit.css /> <script src=qunit.js></script> <script src=prettydate2.js></script> <script> test(prettydate.format, function() { function date(then, expected) { equal(prettyDate.format(2008/01/28 22:25:00, then), expected); } date(2008/01/28 22:24:30, just now); date(2008/01/28 22:23:30, 1 minute ago); date(2008/01/28 21:23:30, 1 hour ago);

11/18

date(2008/01/27 22:23:30, Yesterday); date(2008/01/26 22:23:30, 2 days ago); date(2007/01/26 22:23:30, undefined); }); test(prettyDate.update, function() { var links = document.getElementById(qunit-fixture). getElementsByTagName(a); equal(links[0].innerHTML, January 28th, 2008); equal(links[2].innerHTML, January 27th, 2008); prettyDate.update(2008-01-28T22:25:00Z); equal(links[0].innerHTML, 2 hours ago); equal(links[2].innerHTML, Yesterday); }); test(prettyDate.update, one day later, function() { var links = document.getElementById(qunit-fixture). getElementsByTagName(a); equal(links[0].innerHTML, January 28th, 2008); equal(links[2].innerHTML, January 27th, 2008); prettyDate.update(2008-01-28T22:25:00Z); equal(links[0].innerHTML, Yesterday); equal(links[2].innerHTML, 2 days ago); }); </script> </head> <body> <div id=qunit></div> <div id=qunit-fixture> <ul> <li class=entry id=post57> <p>blah blah blah</p> <small class=extra> Posted <span class=time><a href=/2008/01/blah/57/ title=2008-01-28T20:24:17Z>January 28th, 2008</a></span> by <span class=author><a href=/john/>John Resig</a></span> </small> </li> <li class=entry id=post57> <p>blah blah blah</p> <small class=extra> Posted <span class=time><a href=/2008/01/blah/57/ title=2008-01-27T22:24:17Z>January 27th, 2008</a></span> by <span class=author><a href=/john/>John Resig</a></span> </small> </li> </ul> </div> </body> </html>

12/18

Heres the contents of prettydate2.js: var prettyDate = { format: function(now, time){ var date = new Date(time || ), diff = (((new Date(now)).getTime() - date.getTime()) / 1000), day_diff = Math.floor(diff / 86400); if (isNaN(day_diff) || day_diff < 0 || day_diff >= 31) { return; } return day_diff === 0 && ( diff < 60 && just now || diff < 120 && 1 minute ago || diff < 3600 && Math.floor( diff / 60 ) + minutes ago || diff < 7200 && 1 hour ago || diff < 86400 && Math.floor( diff / 3600 ) + hours ago) || day_diff === 1 && Yesterday || day_diff < 7 && day_diff + days ago || day_diff < 31 && Math.ceil( day_diff / 7 ) + weeks ago; }, update: function(now) { var links = document.getElementsByTagName(a); for ( var i = 0; i < links.length; i++ ) { if (links[i].title) { var date = prettyDate.format(now, links[i].title); if (date) { links[i].innerHTML = date; } } } } }; Here is the result:

13/18

The new prettyDate.update function is an extract of the initial example, but with the now argument to pass through to prettyDate.format. The QUnit-based test for that function starts by selecting all a elements within the #qunit-fixture element. In the updated markup in the body element, the <div id=qunit-fixture></div> is new. It contains an extract of the markup from our initial example, enough to write useful tests against. By putting it in the #qunit-fixture element, we dont have to worry about DOM changes from one test affecting other tests, because QUnit will automatically reset the markup after each test. Lets look at the first test for prettyDate.update. After selecting those anchors, two assertions verify that these have their initial text values. Afterwards, prettyDate.update is called, passing along a fixed date (the same as in previous tests). Afterwards, two more assertions are run, now verifying that the innerHTML property of these elements have the correctly formatted date, 2 hours ago and Yesterday.

Refactoring, Stage 2
The next test, prettyDate.update, one day later, does nearly the same thing, except that it passes a different date to prettyDate.update and, therefore, expects different results for the two links. Lets see if we can refactor these tests to remove the duplication. <!DOCTYPE html> <html> <head> <meta http-equiv=Content-Type content=text/html; charset=UTF-8 /> <title>Refactored date examples</title> <link rel=stylesheet href=qunit.css /> <script src=qunit.js></script> <script src=prettydate2.js></script> <script> test(prettydate.format, function() { function date(then, expected) { equal(prettyDate.format(2008/01/28 22:25:00, then), expected); } date(2008/01/28 22:24:30, just now); date(2008/01/28 22:23:30, 1 minute ago); date(2008/01/28 21:23:30, 1 hour ago); date(2008/01/27 22:23:30, Yesterday); date(2008/01/26 22:23:30, 2 days ago); date(2007/01/26 22:23:30, undefined); }); function domtest(name, now, first, second) { test(name, function() { var links = document.getElementById(qunit-fixture). getElementsByTagName(a); equal(links[0].innerHTML, January 28th, 2008); equal(links[2].innerHTML, January 27th, 2008); prettyDate.update(now); equal(links[0].innerHTML, first); equal(links[2].innerHTML, second); }); } domtest(prettyDate.update, 2008-01-28T22:25:00Z:00, 2 hours ago, Yesterday);

14/18

domtest(prettyDate.update, one day later, 2008-01-29T22:25:00Z:00, Yesterday, 2 days ago); </script> </head> <body> <div id=qunit></div> <div id=qunit-fixture> <ul> <li class=entry id=post57> <p>blah blah blah</p> <small class=extra> Posted <span class=time><a href=/2008/01/blah/57/ title=2008-01-28T20:24:17Z>January 28th, 2008</a></span> by <span class=author><a href=/john/>John Resig</a></span> </small> </li> <li class=entry id=post57> <p>blah blah blah</p> <small class=extra> Posted <span class=time><a href=/2008/01/blah/57/ title=2008-01-27T22:24:17Z>January 27th, 2008</a></span> by <span class=author><a href=/john/>John Resig</a></span> </small> </li> </ul> </div> </body> </html> Lets run it:

15/18

back to the start


With that in place, lets go back to our initial example and see what that looks like now, after the refactoring. <!DOCTYPE html> <html> <head> <meta http-equiv=Content-Type content=text/html; charset=UTF-8 /> <title>Final date examples</title> <script src=prettydate2.js></script> <script> window.onload = function() { prettyDate.update(2008-01-28T22:25:00Z); }; </script> </head> <body> <ul> <li class=entry id=post57> <p>blah blah blah</p> <small class=extra> Posted <span class=time><a href=/2008/01/blah/57/ title=2008-01-28T20:24:17Z><span>January 28th, 2008</span></a></span> by <span class=author><a href=/john/>John Resig</a></span> </small> </li> <li class=entry id=post57> <p>blah blah blah</p> <small class=extra> Posted <span class=time><a href=/2008/01/blah/57/ title=2008-01-27T22:24:17Z><span>January 27th, 2008</span></a></span> by <span class=author><a href=/john/>John Resig</a></span> </small> </li> <li class=entry id=post57> <p>blah blah blah</p> <small class=extra> Posted <span class=time><a href=/2008/01/blah/57/ title=2008-01-26T22:24:17Z><span>January 26th, 2008</span></a></span> by <span class=author><a href=/john/>John Resig</a></span> </small> </li> <li class=entry id=post57> <p>blah blah blah</p> <small class=extra> Posted <span class=time><a href=/2008/01/blah/57/ title=2008-01-25T22:24:17Z><span>January 25th, 2008</span></a></span> by <span class=author><a href=/john/>John Resig</a></span> </small> </li> <li class=entry id=post57> <p>blah blah blah</p> <small class=extra>

16/18

Posted <span class=time><a href=/2008/01/blah/57/ title=2008-01-24T22:24:17Z><span>January 24th, 2008</span></a></span> by <span class=author><a href=/john/>John Resig</a></span> </small> </li> <li class=entry id=post57> <p>blah blah blah</p> <small class=extra> Posted <span class=time><a href=/2008/01/blah/57/ title=2008-01-14T22:24:17Z><span>January 14th, 2008</span></a></span> by <span class=author><a href=/john/>John Resig</a></span> </small> </li> <li class=entry id=post57> <p>blah blah blah</p> <small class=extra> Posted <span class=time><a href=/2008/01/blah/57/ title=2008-01-04T22:24:17Z><span>January 4th, 2008</span></a></span> by <span class=author><a href=/john/>John Resig</a></span> </small> </li> <li class=entry id=post57> <p>blah blah blah</p> <small class=extra> Posted <span class=time><a href=/2008/01/blah/57/ title=2007-12-15T22:24:17Z><span>December 15th, 2008</span></a></span> by <span class=author><a href=/john/>John Resig</a></span> </small> </li> </ul> </body> </html> The running example:

17/18

For a non-static example, wed remove the argument to prettyDate.update. All in all, the refactoring is a huge improvement over the first example. And thanks to the prettyDate module that we introduced, we can add even more functionality without clobbering the global namespace.

conclusion
Testing JavaScript code is not just a matter of using some test runner and writing a few tests; it usually requires some heavy structural changes when applied to code that has been tested only manually before. Weve walked through an example of how to change the code structure of an existing module to run some tests using an ad-hoc testing framework, then replacing that with a more full-featured framework to get useful visual results. QUnit itself has a lot more to offer, with specific support for testing asynchronous code such as timeouts, AJAX and events. Its visual test runner helps to debug code by making it easy to rerun specific tests and by providing stack traces for failed assertions and caught exceptions. For further reading, check out the QUnit Cookbook.

ABOUT THIS ARTICLE


Jrn is a freelance web developer, consultant and trainer, based in Cologne, Germany. Jrn evolved jQuerys testsuite into QUnit, a JavaScript unit testing framework, and maintains it. He created and maintains a number of popular plugins. As a jQuery UI development lead, he focuses on the development of new plugins, widgets and utilities.

ONLINE RESOURCES Quint - introduction http://qunitjs.com/intro/


Smashing magazine http://www.smashingmagazine.com/ JQuery http://jquery.com

http://bassistance.de/about/

@bassistance

appliness

DONT WORRY, BE APPLI

Styling your App with Twitter Bootstrap


Introduction
Twitter Bootstrap is an open source toolkit to help you quickly create visually pleasing interfaces for your web and mobile apps. According to this article its the most watched and forked repository in GitHub. A couple of developers who work for Twitter wrote the framework (hence the name), you can follow them on twitter at (@mdo and @fat). Theres a great article written by them explaining how and why they built the toolkit here. Its used by a wide variety of websites and mobile apps, and theres actually a URL dedicated to showing off some those sites built with Twitter Bootstrap here.

what is it?
The Twitter Bootstrap toolkit addresses most common scenarios for styling an app, including layout and various components. Theres a base toolkit made up of HTML5/CSS3/JavaScript, and then a set of plugins written in JavaScript that can be used to provide additional functionality including popovers, dropdowns, carousel content, modals and more. They also provide a nifty tool you can use to customize your download to only include the support for the specific features you need rather than grabbing the whole repository to help keep file sizes at a minimum. The framework is built on LESS, so you have that

ou Playgr

nd

Difficulty
- rookie - intermediate - expert

- HTML t - JavaScrip - CSS

Todo list
- stylize - colorize - mobilize
by Holly Schinsky

option as well when using and extending the toolkit for your own needs. If youre developing for mobile, their latest version 2.0 includes support for responsive design to help you style for multiple devices by scaling across resolutions. The 12-column grid system includes options for both fixed and fluid layouts. The toolkit is extensive and too much to cover in a blog post, but I will highlight a bunch of the features with code snippets here to give an idea of what it entails. For a more detailed feature-by-feature tutorial, see this link from w3resource or the examples on the Twitter Bootstrap site itself.

examples
In this section Ill highlight some specific features from Twitter Bootstrap including a little bit of information about the feature with a screenshot and code snippet. Buttons With Twitter Bootstrap you can style your HTML buttons with predefined classes to better indicate the type of action they might perform. For instance, the default .btn class will cause the button to be a light grey/white. However, you can specify the .btn-warning class to style it yellow, .btn-success for a green button, .btn-danger for red etc. See the code snippet below to find the specific class names used to style the buttons in the screenshot:

<button class=btn dropdown-toggle data-toggle=dropdown>Action <span class=caret></span></button> <button class=btn btn-primary dropdown-toggle data-toggle=dropdown>Action <span class=caret></span></button> <button class=btn btn-danger dropdown-toggle data-toggle=dropdown>Danger <span class=caret></span></button> <button class=btn btn-warning dropdown-toggle datatoggle=dropdown>Warning <span class=caret></span></button> <button class=btn btn-success dropdown-toggle datatoggle=dropdown>Success <span class=caret></span></button> <button class=btn btn-info dropdown-toggle data-toggle=dropdown>Info <span class=caret></span></button> <button class=btn btn-inverse dropdown-toggle datatoggle=dropdown>Inverse <span class=caret></span></button>

2/15

Progress Bars There are also built-in styles available for easily creating a progress bar component using the .progress with a .bar class and customizing it more specifically with the .progress-xx classes where xx is the type of progress to indicate similar to the button styles (info, danger, success, warning etc). An example is shown below.

<div class=progress <div class=bar </div> <div class=progress <div class=bar </div> <div class=progress <div class=bar </div> <div class=progress <div class=bar </div>

progress-info style=margin-bottom: 9px;> style=width: 20%></div> progress-success style=margin-bottom: 9px;> style=width: 40%></div> progress-warning style=margin-bottom: 9px;> style=width: 60%></div> progress-danger style=margin-bottom: 9px;> style=width: 80%></div>

You can further customize the style of your progress bar by specifying .progress-striped to make the bar striped (versus solid), and .active to then animate those stripes:

<div class=progress progress-striped active> <div class=bar style=width: 40%;></div> </div> Button Groups There are times where you will want to show some buttons as more of a set, or composite component. You can use Twitter Bootstrap classes to achieve this effect by simply specifying a .btn-group class on a div element and then supplying the set of HTML button components within it as shown below:

<div class=btn-group style=margin: 9px 0;> <button class=btn>Left</button> <button class=btn>Middle</button> <button class=btn>Right</button> </div>

3/15

Tabs Horizontal/Vertical (and with dropdowns) You can specify tabs using the .nav class along with the .nav-tabs. This next example shows how you can have not only tabs but also a tab that includes a drop-down menu with a caret icon via the .dropdown and .caret class.

<ul class=nav nav-tabs> <li class=active><a href=#>Home</a></li> <li><a href=#>Portfolio</a></li> <li class=dropdown> <a class=dropdown-toggle data-toggle=dropdown href=#>Services <b class=caret></b></a> <ul class=dropdown-menu> <li><a href=#>Link 1</a></li> <li><a href=#>Link 2</a></li> </ul> </li> </ul> There are another set of tab classes that can be used on a div element to specify that content be .tababble and to specify which position to place the tabs (left/right). You then specify the .tab-content with multiple .tab-pane classes to specify the content of each tab. An example is shown below:

4/15

<div class=tabbable tabs-left> <ul class=nav nav-tabs> <li class=active><a href=#lA data-toggle=tab>Section 1</a></li> <li><a href=#lB data-toggle=tab>Section 2</a></li> <li><a href=#lC data-toggle=tab>Section 3</a></li> </ul> <div class=tab-content> <div class=tab-pane active id=lA> <p>Im in Section A.</p> </div> <div class=tab-pane id=lB> <p>Howdy, Im in Section B.</p> </div> <div class=tab-pane id=lC> <p>And this is Section C.</p> </div> </div> </div>

NavBar Use the .navbar class to create a navigation bar component with content. Inside the navbar, you can use the .navbar-inner class and .nav-search for displaying a search text input and aligning it left or right as shown in the example:

<div class=navbar> <div class=navbar-inner> <div class=container> <!-- brand class is from boostrap.css --> <a class=brand href=#>My Brand</a> <div class=nav-collapse> <ul class=nav> <li class=active><a href=#>Home</a></li> <li><a href=#>Services</a></li> <li class=dropdown> <a href=# class=dropdown-toggle datatoggle=dropdown>Dropdown <b class=caret></b></a> <ul class=dropdown-menu> <li><a href=#>Action 1</a></li> <li><a href=#>Action 2</a></li> <li class=divider></li> <li class=nav-header>Header</li> <li><a href=#>Separated action</a></li> </ul> </li> </ul> <form class=navbar-search pull-left> <input type=text class=search-query placeholder=Search> </form> </div><!-- /.nav-collapse --> </div> </div><!-- /navbar-inner --> </div><!-- /navbar -->

5/15

Form Controls Use the HTML form controls with predefined classes for .btn, .checkbox, .help-block, text, etc. The .well class can be used to surround the content with a border box to make it stand out as shown below:

<form class=well> <label>Label name</label> <input type=text class=span3 placeholder=Type something> <span class=help-block>Example block-level help text here.</span> <label class=checkbox> <input type=checkbox> Check me out </label> <button type=submit class=btn>Submit</button> </form> Icons by Glyphicons (for buttons, navigation etc) Twitter Bootstrap also comes with several icon classes for embellishing your buttons and lists. An example of some of them is shown below, but for the complete list of available icons, see this list.

6/15

<div class=btn-group> <a class=btn href=#><i class=icon-align-left></i></a> <a class=btn href=#><i class=icon-align-center></i></a> <a class=btn href=#><i class=icon-align-right></i></a> <a class=btn href=#><i class=icon-align-justify></i></a> </div> <p> <a class=btn href=#><i class=icon-refresh></i> Refresh</a> <a class=btn btn-success href=#><i class=icon-shopping-cart iconwhite></i> Checkout</a> <a class=btn btn-danger href=#><i class=icon-trash icon-white></i> Delete</a> </p> <div class=btn-group> <a class=btn btn-primary href=#><i class=icon-user icon-white></i> User</a> <a class=btn btn-primary dropdown-toggle data-toggle=dropdown href=#><span class=caret></span></a> <ul class=dropdown-menu>

<li><a href=#><i class=icon-pencil></i> Edit</a></li> <li><a href=#><i class=icon-trash></i> Delete</a></li> </ul> </div> </div> <p> <a class=btn href=#><i class=icon-refresh></i> Refresh</a> <a class=btn btn-success href=#><i class=icon-shopping-cart iconwhite></i> Checkout</a> <a class=btn btn-danger href=#><i class=icon-trash icon-white></i> Delete</a> </p> <p> <a class=btn btn-large href=#><i class=icon-comment></i>Comment</a> <a class=btn btn-small href=#><i class=icon-cog></i> Settings</a> <a class=btn btn-small btn-info href=#><i class=icon-info-sign iconwhite></i> More Info</a> </p> Navigation List Twitter Bootstrap comes with various navigation styles you can use to create lists, tabs and pills for navigating between content. Use .nav and .nav-list along with .nav-header to specify header text for your list.

<ul class=nav nav-list> <li class=nav-header> List header </li> <li class=active> <a href=#>Home</a> </li> <li> <a href=#>Library</a> </li> ... </ul>

7/15

Alerts Use the .alert class on a div element for creating alert boxes. For alerts requiring more than one line of text, further qualify it with the .alert-block class. To style it with a visual indicator of the type of alert, add the .alert-xx class where xx is again similar to the button and progress-bar style classes of info, warning, danger, etc. An example is shown below:

<div class=alert alert-block alert-error> <a class=close data-dismiss=alert href=#>X</a> <h4 class=alert-heading>Error!</h4> Please try again... </div> <div class=alert alert-block alert-success> <a class=close data-dismiss=alert href=#>X</a> <h4 class=alert-heading>Success!</h4> Congratulations, you have successfully submitted. </div> <div class=alert alert-block alert-info> <a class=close data-dismiss=alert href=#>X</a> <h4 class=alert-heading>Info</h4> This is some informational text... </div>

8/15

Labels Convert your simple text into a label by specifying a .label class. To visually identify it further, qualify it with the .label-xx classes where xx can have a value of success, warning, important, info and inverse with the resulting colors of each shown in the screenshot below:

<span <span <span <span <span <span

class=label>Default</span> class=label label-success>Success</span> class=label label-warning>Warning</span> class=label label-important>Important</span> class=label label-info>Info</span> class=label label-inverse>Inverse</span>

Badges A badge is often used to visually indicate a count in a small icon. For instance, its often seen to indicate the number of email items unopened in your mailbox, or the amount of updates an app has outstanding. You can use Twitter Bootstrap to create a badge quickly using the .badge class and again further qualify it with a .badge-xx class to indicate a particular color, similar to the labels above:

<span <span <span <span <span <span

class=badge>1</span> class=badge badge-success>2</span> class=badge badge-warning>4</span> class=badge badge-important>6</span> class=badge badge-info>8</span> class=badge badge-inverse>10</span>
9/15

Thumbnails You can use the .thumbnail class on a div element to contain content such as an image or video clip surrounded by a nice border such as shown below:

<div class=thumbnail> <img src=http://placehold.it/260x180 alt=> <h5>Thumbnail label</h5> <p>Thumbnail caption right here...</p> </div> Typography Twitter Bootstrap has a class called .hero-unit that is used to showcase text content. It basically creates a bordered box where you can then include what you would like to highlight such as shown below:

<div class=hero-unit> <h1>Heading</h1> <p>Tagline</p> <p> <a class=btn btn-primary btn-large> Learn more </a> </p> </div>
10/15

Tables Use the .table class to apply the table styles from Twitter Bootstrap. Theres also a .table-striped class that can be used to cause the rows to alternate colors for readability.

<div class=span8> <table class=table table-striped> <thead> <tr> <th>#</th> <th>First Name</th> <th>Last Name</th> <th>Username</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <td>2</td> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <td>3</td> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> </tbody> </table> </div> </div>

11/15

Layout/Built-in Grid System


Twitter Bootstrap comes with a 12-column responsive grid system that can be used as a default or fluid layout. The default layout is a 940px centered layout, typically used for websites, where the fluid layout is based on percentages and min/max widths and is, thus, more flexible. The fluid layout is particularly useful when building apps for mobile. You use the grid system by setting up div elements that specify predefined .row and .span classes for rows and columns respectively. The spans need to add up to 12 and your content will flow according to the span class chosen for that particular content (content within .span2 might be a sidebar, with content in .span10 being the body for a website for instance). So for instance, you may have a row with three .span4 classes used in a container, or a layout with 2 .span3 divs and a .span6, an example of the markup is shown below: <div class=container> <div class=row> <div class=span4> <!--content--> </div> <div class=span4> <!--content--> </div> <div class=span4> <!--content--> </div> </div> </div> Heres another example of some markup with a screenshot to illustrate: <div class=container> <div class=row> <div class=span4> <h2>Column 1</h2> <p>Morbi fringilla, arcu et pharetra ornare, arcu dolor tinc idunt erat, non ornare nisl diam vitae orci. Nulla eu eros non ligula luctus aliquet. Morbi tempus laoreet urna, nec aliquam odio dapibus at. Nam in libe ro ante. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque et libero eu tortor eleifend vestibulum. Ae nean molestie velit sed lectus placerat malesuada. </p> <p><a class=btn btn-inverse btn-large href=#>Go</a></p> </div> <div class=span4> <h2>Column 2</h2> <p>Sed nec iaculis elit. Donec gravida risus ante, quis sem per sem. Pellentesque sapien eros, sollicitudin hendrerit tincidunt eu, el ementum ut velit. Vivamus ultricies suscipit mauris, at accumsan urna pel lentesque non. Integer mollis justo non urna commodo ut tincidunt arcu ven enatis. Nullam in libero id tellus posuere sollicitudin. Vestibulum eu dictum purus. Fusce dignissim facilisis pellentesque. Duis at risus eget magna mat tis venenatis et non mi. </p> <p><a class=btn btn-info btn-large href=#>Info</a></p> </div> <div class=span4> <h2>Column 3</h2> <p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis

12/15

in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermen tum massa justo sit amet risus. Fusce dignissim facilisis pellentesque. Duis at risus eget magna mattis venenatis et non mi.</p> <p><a class=btn btn-success btn-large href=#>Read More...</a></p> </div> </div> </div>

To create containers with a fluid layout, you simply specify fluid on the container and row class used, such as follows: <div class=container-fluid> <div class=row-fluid> <div class=span2> <!--Sidebar content--> </div> <div class=span10> <!--Body content--> </div> </div> </div>

Responsive Design
In version 2.0 of Twitter Bootstrap, media queries were added and used to check screen widths and modify components for a better fit and layout depending on space available. It basically causes the default column sizes to change and the content to reflow depending on available width. For instance, the predefined media queries in Twitter Bootstrap will cause the columns to stack vertically when the width is smaller than 767px. The bootstrap-responsive.css file needs to be included for the media queries to apply. You can see it by viewing their website on a mobile device vs the web. You can read more about the 2.0 version becoming responsive here.

13/15

Plugins
There are a set of plugins written in JavaScript that can also be downloaded and used with Twitter Bootstrap to add life to the components to do things like typeahead, popover boxes, carousels, transitions, adding toggle or event handling and more. Below are a couple of code samples and screenshots using plugins: Typeahead Example You can create a typeahead input control by specifying a data-provider attribute which can be used to supply set of data to be matched against when a user starts typing into a field as shown below so it can be quickly selected:

<input type=text class=span3 style=margin: 0 auto; dataprovide=typeahead data-items=4 data-source=[Apples,Bananas,Cherries,Dates,Eggplants,Figs ,Grapes,Honeydew,Kiwi,Mango,Peaches,Plums,Raspberries,Strawber ries,Watermelon,Zucchini]> Popover Example A popover is often used to show an overlay with content on a tablet device. You can specify a data-content and the data-original-title attribute can be specified to control what is shown in the popover, such as below:

14/15

<a href=# class=btn btn-info rel=popover id=el3 data-content=This is my popover content data-original-title=My Popover Title>hover for popover</a> The JavaScript needed to pop up the Popover overlay is shown here: <script language=javascript> $(function () { $(#example).popover(); $(#el3).popover(); }); function showPopup() { $(#el3).popover(show) } function hidePopup() {

} </script>

$(#el3).popover(hide)

For a complete list of available plugins and examples, see this link.

Where to go from here


In summary, you should definitely take a moment to try out Twitter Boostrap with your next application or website design. With the responsive layout in the latest version and the useful grid system, it can be an invaluable resource to get your application to look professional fast. If youre looking for more information and complements to Twitter Bootstrap, see the highlighted links below: 20 Resources that Complement Twitter Bootstrap Twitter Bootstrap Tutorial jQuery Mobile Bootstrap Theme Create Styles for Bootstrap jQuery UI Bootstrap Themes Paid Themes Button Customizer for Bootstrap

ABOUT THIS ARTICLE


Holly Schinsky is an Adobe Developer Evangelist focused on mobile development using PhoneGap, HTML/CSS & JavaScript and has 16+ years experience in software development including a large focus on Adobe Flex and AIR for front-end and mobile development & Java for development on the server-side. She has helped build developer tools such as: Tour de Flex, Adobe AIR Launchpad & PhoneGap templates.

ONLINE RESOURCES Twitter Bootstrap Download http://twitter.github.com/bootstrap/


Twitter Bootstrap jQuery Plugins http://twitter.github.com/bootstrap/javascript.html Twitter Bootstrap Examples http://twitter.github.com/bootstrap/examples.html

http://devgirl.org/

@devgirlFL

appliness

DONT WORRY, BE APPLI

TAME THE MOBILE WEB BEAST!

Andre Jay Meissner ADRESSES IN THIS ARTICLE A CLASSIC CHALLENGE FOR WEB DEVELOPERS ON MOBILE DEVICES: Mobile Web Testing & Debugging. HE SHARES HIS BEST PRACTICES.

MOBILE FIRST AND CONSEQUENCES


Responsive Web Design and Mobile First are among the buzzwords of the year, and there is a reason for that. With the number of Smartphone and Tablet activations growing every day, and countries where a mobile device is the primary way to access the internet, web content is clearly not consumed primarily on huge desktop screens anymore. Back in the day, people tended to deploy a separate mobile version of their offering, often sporting reduced graphics and a lowered featureset, adapting to an intersection of (that years) mobile device capabilities. Modern webworkers are striving to deploy only one version of their offering, serving all kinds of devices and screens at a time. Added, hybrid web apps (e.g., built using PhoneGap), targeting multiple mobile operating systems at a time, are based on HTML, CSS and JS just like any webpage, and use mobile browser engines as their interface rendering engine. Due to the fragmentation in terms of operating systems, browsers and browser versions, testing against a set of relevant web browsers on different desktop operating systems quickly became a mandatory standard task for everybody creating content to be displayed using a browser. In addition to that, web workers now definitely need to test their code against a proper set of mobile browsers, operating systems and their respective versions as well. But - there is always a but - things are not as easy as setting up some virtual machines running IE6 here and Firefox 4 there... read ahead and you will find out why.

ou Playgr

nd

Difficulty
- rookie - intermediate - expert

- Mobile - Inspect - Shadow

Todo list
- test - deploy - debug
by Andre Jay Meissner

THE CHALLENGE

Quality Assurance for the mobile web is not as easy as for the desktop. These are the four major challenges to take into account: 1. You have to test against the growing fragmentation of mobile operating systems and browsers/ versions. This means you need more than your iPhone to do that. 2. You have to test on real devices. Sure, there are simulators or emulators for every relevant mobile operating system available, but these are just simulating rendering your code and assets on an imaginary device. Your users do not consume your content in an emulator or simulator as well, and while it is simply impossible to do realistic simulations of touch gestures it can still be hard to simulate devicespecific issues such as display quality, bandwidth aspects or device-specific features and performance. This means you need physical access to these devices. 3. When youre doing the above, make sure you bring enough patience to go from device to device for simple things like navigating to a URL in production, or a page refresh. Dont even think it will be easy to clear the cache, so make sure you reserve some memory in your brain to remember how to handle the cache on 10+ different browsers and versions. You need screenshots? Oh boy. Without the right environment, testing against a larger set of mobile devices requires a lot of time, as you need to go from device to device basically after each major code change. Oh, and when youre inactive for too long your devices will fall asleep, require to be unlocked or draw your attention with unrelated notifications, away from your project. 4. Most significant: when youve identified a bug on a specific device, do not assume there are developer tools available for that specific mobile scenario. Always assume: there will be no tools available on that specific device your project is firing most of the bugs.
2/10

TWO GENERAL PRACTICAL APPROACHES


We dont do separate code for mobile anymore. Whenever there is something sitting on a webserver for public consumption, its either optimized for all screens and devices, or it will fail for a fraction of the users. Its that easy. So, which way to go, what to test, and how? As always in programming, there is more than one way to accomplish your goals. Over frequent talks and sessions on this topic at conferences, I surveyed webworkers on their usual habits when coding for the mobile web. Sure, there is no black or white, but here is the essence of what people usually do: - Permanent testing during development: From a certain point in production you will constantly preview the code under construction across a set of mobile devices, limiting the number of bugs to a minumum, from day one. - Stage Testing and dedicated Bugfixing: You will develop your project on the desktop as usual, and, from time-to-time, test against simulators or a small number of real devices. A test department (in worse-case-scenarios this department is called customers!) will then do the broad real device testing and report bugs back to you, which you will fix and commit back to your project. Whether that might be seen as a common requirement or not: the ideal way to go is a combination of both. With permanent testing you can easily ensure a high level quality, whether issues on specific browsers require you to dig deeper using that browsers companion tools.

DEBUGGING - WAIT, WHAT?


Regardless on which way you actually learned of a bug in your code, as soon as you reproduced it on the specific device, you will want to investigate what caused the misbehaviour. Did you ever try to access a console or developer tools on a mobile device? Right... There is none! Of course some platforms will provide you with some tooling. Mentioning that, it doesnt really make sense to point you guys to the Safari Mobile Debugger, which actually isnt more than a very truncated JS log, serving indicators but not providing any possibility to dig into the code. Reality is: today you will not find one truly general solution that covers all the mobile goodness out there. So how do we inspect the DOM on that misbehaving mobile fellow? How do we analyze the performance of our code in production, make easy changes directly to the DOM, work it out the way we know and love on desktop browsers? Tools to the rescue! Lets take a look at what is available.

Browser vendors remote inspection tools


Lately, nearly every browser vendor seems to have knocked together some sort of remote inspection and caught up with the functionality Opera Dragonfly already introduced back in 2008. To enable you to access the code in the way it is interpreted by the remote device, in a way you got used to inspecting a desktop browser. That sounds like it could solve all of your problems, huh? But it is not. Whilst tools like the Chrome for Android Inspector, Firefox for Android Remote Debugging and the iOS6 Safari Web Inspector each sport a good featureset, they all come with a number of downsides (Note: iOS6 has not been released by the time of composing this article, but rumors read it is going to land in the neighborhood of the capabilities of Chrome and Firefox).
3/10

Some tools are only available for a specific desktop platform and/or mobile OS and/or browser version (e.g., the current WebKit Remote Debugger for Safari: Mac only, iOS5 only). Others only support devices USB-wired to your desktop, which is already a pain when you want to control two or more devices. Some require additional tools (e.g., SDKs) to be installed and configured, and all of them simply require too much stuff to maintain for supporting such a limited fraction of your test field: namely one specific browser on one specific platform in just its newest version. Reads cool, but will only help you with (a growing number of) fractions of your real life needs. Bummer. TOOL Opera Dragonfly by Opera TYPE On remote device SUPPORTS Opera Presto 2.1+ equipped browsers: Opera Mobile 9.5+ Opera Mobile 11+ for tablets Opera 10+ emulator iOS4 iOS5 PRO Covers nearly all relevant versions of Opera out there (Opera Mini not supported) CONTRA AUTHORS VOTE Proprietary vertical solution

Safari Mobile Debugger by Apple (included in Mobile Safari) WebKit Remote Debugger by Apple

On device

Convenient: built JS Log is in crippled no DOM inspection or editing Simulator only requires Mac OS/not for Windows requires Xcode, iOS4 + iOS5 SDKs no iOS4 testing a lot to setup and maintain compared to the benefits runs PhoneGap and chrome-less webapps plus native apps that use UIWebView remote DOM

Barely useful, if at all

Simulator

iOS5

Proprietary vertical solution

iWebInspector by Maximiliano Firtman

Simulator

iOS5

uses WebKit Limited use Remote Debugger - see the above line for the flipsides requires GDT requires ADK requires USB (!) a lot to setup and maintain compared to the benefits Firefox 15 (beta) only a lot to setup and maintain compared to the Proprietary vertical solution

Chrome for Android Web Inspector by Google

On remote device

Chrome on Android 4+

Firefox for On remote Firefox 15 Android Remote device (beta) on ^^^ SCROLL THE CONTENTS OFAndroid THIS TABLE Debugging 2.2+ by Mozilla

remote DOM Android 2.2+ Wireless

4/10

Proprietary vertical solution

3rd Party remote inspection and simulating tools


Whenever there is a tricky problem to solve, our planet features some insanely smart people to feel challenged and provide the community with a solution. So is the case with mobile web testing & debugging. iWebinspector by Maximiliano Firtman (@firt) is such a tool, leveraging the factory-obscured capability of WebKit, provided it has hixie-76 support, to open remote debugging sessions. Anyhow, it doesnt allow you to connect to real devices, so youre stuck with simulators. Socketbug by Peter Schmalfeldt (@mrmidi) adds webOS Support to your iOS and Android test range and provides simulator as well as real device support. And, it connects wirelessly and sports a real neat console with autocompletion - which is a huge plus. Anyhow: you still need to go from device to device when you are testing a broad range of platforms (remember: which you should do!). jsconsole, and of course js_bin, are two awesome additions to our toolbox made by Remy Sharp (@ rem). For those of you familiar with jQuery, jsconsole offers true remote inspection of any browser out there (desktop and mobile), by inserting a simple line of code into your project and enabling you to walk along the remote DOM using jQuery. Pretty neat - for those loving a console. Whether js_bin is a genius collaboration tool and snippet tester (and more), it has not been made to solve any of our primary problems discussed in this article - so why do I mention it? Because it rocks in combination with other tools in this article. Read ahead. Weinre (WebInspectorRemote), developed by Patrick Mueller (@pmuellr) and contributed to PhoneGap, leverages WebKits Web Inspector project and therefore presents us with a UI for remote inspection many of you are familiar with. And, it connects wirelessly to any Android 2.2+ PhoneGap 0.9.2+ App, Android native and iOS 4.2+ mobile Safari browsers, as well as the BlackBerry 6+ simulator and webOS 2+.

But (again!): even with all these awesome helpers up, running and constantly maintained in your toolchain - you still need to go from device to device! This is absolutely fine and sufficient if youre targeting a specific bug, on a specific browser, and/or OS version. No argument, there is a need and relevant use case for each of these tools. But (But #9) - what if you simply want to constantly check your code in production against a relevant set of real devices, without hassle, including remote code inspection and debugging and much more? The good news: there are three apps for that. ;)

5/10

INTRODUCING: ADOBE SHADOW


Back in March 2012 Adobe introduced Shadow, an inspection and preview tool that solves a good number of your everyday needs. Shadow is currently available in a preview release for Mac and Windows as well as iOS and Android, including the Kindle Fire. It consists of three components: - An application, running on your production computer - An extension for Chrome, running inside your production browser - The Shadow App, running on your Tablets and Smartphones I work for Adobe so believe me or not, but this tool blew me away from the day when I have been allowed to sneak at the blueprints. It is not only a huge timesaver, its just plain fun to see some ten, twenty or even more devices in sync with your local browser (there is no limit on connected devices). And with Shadow, that is not the only new tool on your belt: Synced Browsing: Shadow syncs your local Chrome with all connected devices. Open a URL and navigate on the production computer, and your devices follow along Remote Inspection and Debugging: Shadow integrates Weinre (in the cloud or on your local machine), so you can open a remote inspection session directly from your computer and see the usual highlighting on the device when inspecting the code. Changes to the code happen instantly on the device Multiple Refresh Cache: Clear the Cache and reload your content on connected devices with a single action from your computer Screenshots: Using Shadow, taking screenshots from connected devices becomes a no-brainer. The screenshots will be transferred to your computer along with a sidecar file containing device info such as device type, OS/version, pixel density and content payload Breakout on device: You can switch to another browser on the device using included Copy URL and Open in browser commands. Switching between browsers doesnt get much easier than this It even works with js_bin: Use js_bin to code snippets collaboratively and test them directly on your device farm. It doesnt get much cooler than that! There is even more goodness, but enough for the words, just see it in action. Watch Bruce Bowman demo the initial release of Adobe Shadow in this quick video:

6/10

Also see Remy Sharp demoing Shadow and js_bin in this video (tap to play):

Shadow is available for free on Adobe Labs: http://labs.adobe.com/technologies/shadow/ You might also want to check out the Shadow Team Blog, which features some nice tricks on working with Virtual Hosts, Typekit on localhost, combining Shadow with LiveReload and other useful information: http://blogs.adobe.com/shadow/

THE RIGHT SET OF DEVICES FOR THE TEST


While it might be a requirement for global webservices (like YouTube) to be tested against every device and OS version available on the planet, this might be a bit too timestretching for your specific project and simply wouldnt be an economic scenario for a niche offering like the new website for a small local business. So how do you narrow down the list? 1. It depends on the specific project. As a rather extreme example, if you do the relaunch of a store focussing on accessories for iOS devices, you can assume there wont be that much traffic from e.g., Android or BlackBerry. 2. To validate your assumptions, and given the scenario that your project already is out on the web for a while, you will want to get your hands on the existent analytics data. If you work on a new offering that has no legacy stats, connect with similar offerings on the web and try to acquire the relevant access statistics from two or more competitiors. 3. Publicly available, general stats can help validate your assumptions, but make sure to take geographic aspects into account. It doesnt make much sense to target your local business against global statistics of services like statcounter.com. The scenario in your country might look completely different. It always helps to combine different sources of statistics information to validate against each other.
7/10

4. When analyzing the stats, invest some work in adjusting them to get a real life view on the data.

Exclude corporate IPs and, if not possible, find out which devices and webservices the company is using on its own behalf and deduct them from the stats. For example, if your project in question is a financial company that runs a web-based mortgage calculator used daily by 5000 sales people in the field, all equipped with company Galaxy Pads, make sure you filter out the peak of Android requests from your view on the stats. 5. When you narrowed it down to a set of most common devices/OSes based on pageviews and access stats, dont yet drop the exotic ones. If your project lives to generate conversions, make sure to take the conversion rates and customer lifetime value into account. It might be the most valuable customers of your project that dont run the devices that rank Top 3 in your access stats! Analyze your stats again, based on that. 6. When you have found your target list and there are two or more devices running the same OS, test against the slowest device. Of course it is valid fun to check how well your code performs on a new iPad, but you should work the ladder from the iPhone 3 up instead of walking it back down. Looking at the incredible amount of different Smartphones and Tablets out there, it can be pretty hard to come up with your personal shortlist. I spent a reasonable amount of time to compile that list for myself, one that features an average in device capabilities and performance, looking on OS, chipsets, performance, features, screen size and density. I am sharing it with you in the hope that it saves you from reading through boring tech specs and you might spend that time for something better:
Symbian S60 Nokia N95 Android 2.1 HTC Desire Android 2.2 Samsung Galaxy S Android 2.3 Fork Amazon Kindle Fire Android 3.1 Sony Tablet S Android 3.2 Samsung GT-P7100 Android 4.1 Galaxy Nexus Blackberry OS 5 Torch 9000, Bold 9700 Blackberry OS 6 Bold 9700 Windows Phone 7.5 Nokia Lumia 900 iOS4 iPad1, iPod touch, iPad2, iPhone3G(S) iOS5, iOS6 iPad3, iPad2, iPhone4(S) webOS Palm Pixi or Pre

(Disclaimer: this research is EU focussed, you might have other devices in your geos focus. I also didnt include Bada and MeeGo, feel free to add your specific needs and to send me your suggestions). A word on iOS4/5: Apple does not provide an official way to downgrade devices. And it can be really hard to find a used device still running iOS4. Be aware, you will not be able to downgrade without access to so called SHSH blobs. But you might find owners that have backed up these SHSH blobs, and if you own iOS devices, start to backup your SHSH blobs for future reference. There are tools and howtos available on the web. Two great articles by Brad Frost (@brad_frost) and David Blooman (@dblooman) that helped me in defining my current shortlist: http://bradfrostweb.com/blog/mobile/test-on-real-mobile-devices-without-breaking-the-bank/ http://mobiletestingfordummies.tumblr.com/post/20056227958/testing

8/10

DONT ROB GRANDMA!


If youre not in the lucky situation of having access to a good selection of devices, now is the time for some shopping. Yes, I mean spending money. Its a good investment, I promise. Your customers will love you (of course without even knowing you) and the mobile web will love you as well. So go for it. Of course you dont need to actually buy everything (new), and most likely you wont have to aquire brand new devices. Here are some tips for you how to quickly build up your device test farm and necessary supplies whilst saving your precious budget for the brand new devices that you planned to acquire anyway. ;) You have a new mission. From now on, the next time you stroll through a flea market, youre on the lookout for missing devices, chargers, cables and replacement batteries. Oh, and make sure you stroll through flea markets. Identify the people in your company (and in your friends & families companies!) that are handing out mobile devices to employees. These guys most likely have a drawer full of used devices waiting for recycling, but the gadgets are actually just waiting for - you. Usually you will do a favor to these people in taking some ballast off them. So go for it! I know people that refused from this simple method because they couldnt imagine people NOT selling their old gear - so its on the list: let your friends & family know about your needs! Simply ask everybody for dispensable devices. They have them, somewhere. Or know somebody that does As your device farm might include some non-Wifi devices, you will need some SIM cards to connect to the internet. Some guys, like the Nokia N95, dont even let you connect via Wifi when there is no SIM present. Look out for promo- or very cheap SIMs, you will find them glued on magazines, as handouts in shopping malls and sometimes you might want to grab the ridiculously cheap promo of the week in the supermarket around the corner. Yes, it can make sense to let your family know about that need as well - or do you really read the supermarket promo ads in the local newspaper? ;) Good hunting!

OPEN DEVICE LABS TO THE RESCUE!


I realize that not everybody is as geeky as me, owning and nurturing a growing list of (currently 28 - 29) internet connected mobile devices. Larger companies often run device labs sporting some 200+ devices, but, unfortunately, not every webworker is in the situation or willing to spend a years earnings on the latest (and most relevant old fashioned) devices. If you want to avoid stepping into the necessary frequent care on a longer list of gadgets, there is a growing list of truly awesome people who have planted the seed for so called Open Device Labs around the globe (basically this is just another European invention, but I strongly assume other continents will follow). So if you want to test on a broad range of devices, check out an Open Device Lab near to you - and dont forget to contribute! Brighton UK http://clearleft.com/testlab/ London UK http://shaundunne.github.com/deviceLibrary/ Exeter UK http://www.exeter-web.org/device-library Frome UK (just started) http://cole007.net/blog/111/setting-up-a-mobile-testing-suite Berlin DE http://co-up.de/2012/07/31/open-device-lab.html
9/10

Malm SE http://suhajdab.github.com/modl/

Amsterdam NL http://www.80beans.com/en/blog/2012/08/07/introducing-our-open-test-lab-formobile-device-testing Breda NL http://www.netvlies.nl/openbaar-testlab Helsiniki FI http://meegonetwork.fi/ldp

Know about an Open Device Lab that is not listed here? Add it to my growing list at http://klick-ass.com/awesomeness/avoid-the-tamagotchis-a-list-of-open-device-labs/ please!

CLOSING WORDS
As the modern web shapes, this whole topic is truly under constant development. By the time between writing this article and publishing it, it is most likely that improvements have been made. And quite personally, I am looking forward to each one of them. Due to its complexity and obstacles, todays mobile web testing and debugging is a true experts job - which will not help to improve the overall user experience on the long run. So lets work together and make the mobile web better.

ABOUT THIS ARTICLE


Jay is a passionate diving Enthusiast, Tech Geek and Code Freak, Entrepreneur and BDM/DevRel Web & Mobile at Adobe. He focuses on Webstandards, responsive and Multiplatform Development as well as Gaming. Jay blogs at http://klick-ass.com, can be found on https://alpha.app.net/klick_ass, or met at a conference in your neighborhood soon.

ONLINE RESOURCES Jays blog http://klick-ass.com


Adobe Shadow & HTML tools http://html.adobe.com/ JSBin http://jsbin.com/

http://klick-ass.com

@klick_ass

TE

SA VE TH E

CREATE THE WEB


-TOUR-

Find out how Adobe is helping move the web forward and get a sneak peek at new tools, technologies and services for web designers and developers. Join Adobe for a series of free full-day events to learn about the latest tools and techniques for creating content for the modern web. Topics covered include HTML, CSS, motion graphics, web development and more.

San Francisco
September 24th

DA

London
October 2nd

Tokyo
October 9th

Sydney
October 11th

REGISTER

REGISTER

REGISTER

REGISTER

appliness

DONT WORRY, BE APPLI

Apply and arrays: three tricks


This article describes three tricks for working with arrays via apply.

The apply method


apply is a method that all functions have. Its signature is func.apply(thisValue, [arg1, arg2, ...]) Ignoring thisValue, the above invocation is equivalent to: func(arg1, arg2, ...) So, apply lets us unwrap an array into the arguments of a function call. Lets look at three tricks that apply allows us to perform.

Trick 1: hand an array to a function that does not accept arrays


JavaScript does not have a function that returns the maximum of an array of numbers. However, there is the function Math.max that works with an arbitrary number of number-valued arguments. Thanks to apply, we can use that function for our purposes: > Math.max.apply(null, [10, -1, 5]) 10

ou Playgr

nd

t - JavaScrip re - Undersco - Arrays

Difficulty
- rookie - intermediate - expert

Todo list

- apply - eliminate

- flatten

by Dr. Axel Rauschmayer

Trick 2: eliminate holes in arrays


Holes in arrays Quick reminder: In JavaScript, an array is a map from numbers to values. So there is a difference between a missing element (a hole) and an element having the value undefined [1]. The former is skipped by the Array.prototype iteration methods (forEach, map, etc.), the latter isnt: > [a,,b].forEach(function (x) { console.log(x) }) a b > [a,undefined,b].forEach(function (x) { console.log(x) }) a undefined b You can also check for the presence of holes via the in operator. > 1 in [a,,b] false > 1 in [a, undefined, b] true But if you read a hole, the result is undefined for both holes and undefined elements. > [a,,b][1] undefined > [a, undefined, b][1] undefined Eliminating holes With apply and Array (which can be used as either a function or a constructor), you can turn holes into undefined elements: > Array.apply(null, [a,,b]) [ a, undefined, b ] The above works, because apply does not ignore holes, it passes them as undefined arguments to the function: > function returnArgs() { return [].slice.call(arguments) } > returnArgs.apply(null, [a,,b]) [ a, undefined, b ] Alas, you are faced with a quirk here. If Array receives a single numeric argument, an empty array is created whose length is the number [2]: > Array.apply(null, [ 3 ]) [ , , ] Therefore, if you need this functionality, it is better to write your own function: function fillHoles(arr) { var result = []; for(var i=0; i < arr.length; i++) { result[i] = arr[i]; } return result; }

2/3

Example: > fillHoles([a,,b]) [ a, undefined, b ] Underscore gives you the _.compact function which removes all falsy values, including holes: > [ > [ > [ _.compact([a,,b]) a, b ] _.compact([a, undefined, b]) a, b ] _.compact([a, false, b]) a, b ]

Trick 3: flatten an array


Task: turn an array of arrays with elements into just an array of elements. Again we use the unwrapping ability of apply to make concat do this work for us: > Array.prototype.concat.apply([], [[a], [b]]) [ a, b ] Non-array elements are added as is: > Array.prototype.concat.apply([], [[a], b]) [ a, b ] applys thisValue must be [] here, because concat is a method, not a non-method function. Only one level of flattening is performed: > Array.prototype.concat.apply([], [[[a]], [b]]) [ [ a ], b ] If you want your code to be self-descriptive, you should consider alternatives, including implementing your own properly named function. Underscore has _.flatten which handles any level of nesting: > _.flatten([[[a]], [b]]) [ a, b ]

ABOUT THIS ARTICLE


Dr. Axel Rauschmayer is a consultant and trainer for JavaScript, web technologies and information management. He blogs at 2ality.com and is currently writing a book on JavaScript.

ONLINE RESOURCES JavaScript: sparse arrays vs. dense arrays http://www.2ality.com/2012/06/dense-arrays.html


ECMAScript.next: Array.from() and Array.of() http://www.2ality.com/2011/07/array-from.html Underscore.js http://underscorejs.org/

http://www.2ality.com/

@rauschma

appliness

DONT WORRY, BE APPLI

Creeps and Weirdos in the CSS Spec

When I look at new modules in the CSS spec, it makes me feel like singing the chorus from a popular Radiohead song from the 90s:

If web standards could talk, I think a lot of them would be humming that regularly. But hey, lets be fair and not leave weirdos out of CSS3 discussions. So in this article, Ill run through a bunch of things from the CSS specifications that you might not have heard of yet. None of this is even close to ready to use (unless it degrades really gracefully), but it will serve to get you familiar with some of the rounded corners and drop shadows of the future.

ou Playgr

ut Im a creep. Im a weirdo. I dont belong here.

nd

- variables - modules - Modernizr

Difficulty
- rookie - intermediate - expert

Todo list
- blend

- toggle - composite

by Louis Lazaris

toggle() Values
According to the spec, the toggle() expression (formerly called cycle()) allows descendant elements to cycle over a list of values instead of inheriting the same value. Thats probably not the most clear explanation, so Ill try to make it easier to understand. The example I like in the spec is the one applied to unordered lists: ul { } list-style-type: disc;

ul ul { list-style-type: toggle(disc, circle, square, box); } With this code, the parent list will use disc while nested lists will cycle through circle, square, and box, respectively. So a list that is four levels deep will use box, and a 5th-level nested list will start back at the beginning of the cycle, using disc.

Variables (finally)
CSS variables have been talked about for a long time. Of course, if youre preprocessing, then you couldnt care less about this in the spec, because preprocessors add this feature out-of-the-box. But now the spec has what seems to be a more definite future mapped out for CSS variables. Heres some simple syntax to show you how they work: :root { var-global-color: navajowhite; } .element { color: $global-color; font-family: var($global-font, Helvetica, sans-serif); } Custom variables are created using the var- prefix, then a custom name of your choosing. When you apply the variable to a property, you prefix it with the dollar sign (like in PHP). Alternatively, you have the option to use the var() expression/function. With var(), youre able to provide a default value as a second argument, which will be used if the supplied variable (the first argument) is not defined. So in the example above, the font stack would be Helvetica, sans-serif because $global-font is not defined. But the color of the text (represented by $global-color) will be navajowhite (yes, thats a valid color name), because weve defined it on the :root element.

2/5

Box Alignment Module


The Box Alignment Module is an attempt to separate simpler alignment issues into a universal set of features that will be available in all other layout modules (flexbox, grid layout, etc). According to the description, it attempts to create a cohesive and common box alignment model to share among all of CSS and defines six new properties, specifically: justify-self align-self justify-content align-content justify-items align-items This new module attempts to address a couple of things: First, these features allow for simple ways to align elements and content that mimic more powerful alignment features in other layout modules like flexbox. This means you can finally do something simple like vertically centering text in a block, without having to resort to all the code overhead of using something larger like flexbox. Second, these new properties are intentionally generic so that they can be used across all layout modules, which is going to be a great benefit to learning the syntax for all the different layout modules. I have to give credit and thanks to Tab Atkins for clarifying this particular module for me on IRC.

@viewport (Device Adaptation)


This one seems pretty exciting and looks to be a nice complement to media queries. From my brief look at the specification, it is intended as a replacement for the viewport meta tag. Heres an example from the spec: @viewport { width: device-width; } @media screen and (min-width: 400px) { div { color: red; } } @media screen and (max-width: 400px) { div { color: green; } } In the example above, were defining the viewport using the @viewport at-rule, then defining some media queries. So if the actual width of the device was 320px, and the size of the window was 960px, then the second media query would be the only one of the two to take effect.
3/5

If not for the @viewport rule, the reverse would happen the first media query would apply but the second would not.

Line Grid Module


The Line Grid Module describes features to align lines and blocks to invisible grids in the document. Some of the potential benefits of this module include improvements in readability through vertical rhythm, better multi-column layouts, improving the vertical rhythm of text before and after images, and enhancing paged media. The spec also points out that this will help the vertical rhythm in East Asian layouts which require this more often than other scripts.

Compositing and Blending


The ability to combine elements with their backgrounds using various effects is nothing new to most web designers. Some of the blending effects described in this module include: multiply screen overlay darken lighten color-dodge color-burn saturation luminosity Look familiar? The features introduced here are very similar to what you find in the layers panel in Photoshop, so when this module starts to get widespread browser support, it will be an easy thing for many designers to incorporate into their toolkit.

Conditional Rules with @supports and @document


This one looks super-cool, and again it looks to be in the very early stages and likely not even close to being ready for use. This module adds two new at-rules that can be used in a manner similar to how we use conditional classes or Modernizrs helper classes. For example, you can fork some CSS that will only be rendered if the browser supports a specific feature: @supports ( display: flexbox ) { .example { background: blue; border: solid 1px white; }
4/5

Additionally, you can use the @document at-rule to apply CSS rules to certain pages, like this: @document domain(impressivewebs.com) { body { font-size: 16px; } } This targets the body element as long as it exists on a page on the specified domain. In addition to domain(), you can use url(), url-prefix(), and regexp().

final warning
As already mentioned, these features are absolutely not ready to use, and in most cases might not be ready for some time. I believe the only one above that has any browser support is CSS Variables, which works in WebKit Nightlies. Most of the modules mentioned above have numerous red issue boxes, demonstrating problems that are still being worked out in the syntax and how browsers should implement them. Of course, if we could abolish old browsers, then these types of cutting-edge features would be much closer to being used fearlessly by more developers. If you have any further info on the statuses of any of these modules or have any corrections to any of the above, please comment. If you want more summaries and code examples on new CSS3 features, check out my CSS3 Click Chart resource which has recently been updated to include some of the above and more. Or you can browse the CSSWGs dev channel folder for links to all sorts of creeps and weirdos in the spec.

ABOUT THIS ARTICLE


Louis Lazaris is a freelance web developer based in Toronto, Canada. He blogs about front-end code on Impressive Webs. Most recently, he has co-authored a book on front-end development published by SitePoint, called HTML5 & CSS3 for the Real World.

ONLINE RESOURCES
Creeps and Weirdos in the CSSWG specification http://dev.w3.org/csswg/ Webkit Nightlies http://trac.webkit.org/changeset/120154 Modernizr http://modernizr.com/

http://www.impressivewebs.com/

@ImpressiveWebs

appliness

DONT WORRY, BE APPLI

How to write a well structured CSS Part I


Special thanks to Nick Cooley for his help and advice.

introduction
CSS patterns, is there such a thing? A pattern of writing proper and well-structured CSS? There are great articles by Jonathan Snook regarding Decoupling HTML and CSS and Nicole Sullivan regarding Object Oriented CSS, however they do not outline how to write a well structured CSS. So the question is is there a point of reference on the common standards for writing a well-structured CSS? As I was trying to explain to a junior developer how to set up a well structured CSS, I was trying to find references on the internet to point them to it. There were a lot of issues I found with the results I got from a Google search: Most of the articles were 2 or more years old. Not that CSS has changed much since (other than the ever changing CSS3); however, we have learned quite a bit on how to set up a well-structured CSS that does require revisiting. Most of the articles were very light in examples and/or guidance. There were plenty of aricles on the syntax of CSS but not much on proper structuring of the file. As a result, I decided to outline the approach I take in writing the CSS for every project. I understand that there are different approaches to writing

ou Playgr

nd

Difficulty
- rookie - intermediate - expert

- LESS - SASS S - COMPAS

Todo list

- begin class

- reset - set default

by Kianosh Pourian

CSS and some may agree or disagree with my approach and I welcome that! I am always eager to discuss a better approach, so feel free to write your agreement or disagreement in the comments section. For every CSS project, I follow these general rules: DRY Dont Repeat Yourself. This means taking advantage of the cascading rules of the stylesheet and writing the minimal amount of CSS in order to apply the styling. Performance to keep the CSS file lightweight, the above rule (DRY) is very important. Consider the CSS specificity and inheritance for better performance (there is a great article on Smashing magazine regarding CSS Specificity). Also, minimizing and removing comments is also important, therefore running the CSS through a minification process can help in keeping it lightweight. Know when to place all CSS styles in a single file and when to break up modular portions of the CSS into its own CSS file. Follow front end development separation of concerns tightly which means that everything that concerns presentation styles should be in the CSS (and only in the CSS). Side Note: The DRY concept of CSS can be better implemented by using tools like SASS, LESS, and COMPASS. Consider looking into these tools and using them in your next project. With the above rules in mind, here are some guidelines to follow:

Start with a reset or normalize CSS


Reset CSS as Eric Meyer states The goal of a reset stylesheet is to reduce browser inconsistencies in things like default line heights, margins and font sizes of headings, and so on. Normalize CSS, a project started by Nicolas Gallagher and Jonathan Neal, performs the following: Preserves useful defaults, unlike many CSS resets. Normalizes styles for a wide range of HTML elements. Corrects bugs and common browser inconsistencies. Improves usability with subtle improvements. Explains what code does using detailed comments. The benefit of using either reset CSS or normalize CSS is that it will give the canvas (i.e., presentation layer) a consistent look in a world marred by inconsistent browser interpertation of the CSS styling. The difference between reset CSS and normalize CSS, is that reset CSS will wipe the canvas clean regardless of which browser is being used while normalize CSS will preserve some defaults and updating the inconsistent ones. Regardless of which one is used, one of the above should be your starting point.

Set default values


Once the reset or normalize CSS has been set, set default values that will govern the entire site. At this point, the governing rule or global defaults like font-family, anchor tag settings, input settings, and etc will be set. The following is an example of global defaults from Tim Wrights site www.csskarma.com: html { text-align:center; overflow-y:scroll;

2/7

-webkit-font-smoothing:antialiased; -webkit-text-size-adjust:none; -moz-text-size-adjust:none; -ms-text-size-adjust:none; text-size-adjust:none; } body { text-align:left; color:#333; position:relative; font: 0.75em/1.5 Sans-serif; } h1,h2,h3,h4,h5,h6 { margin-bottom:24px; font-weight:700; } h1 { font-size:1.5em; line-height:1em; } h2 { font-size:1.375em; line-height:1.0909em; } h3 { font-size:1.25em; line-height:1.2em; } h4 { font-size:1.125em; line-height:1.333em; } h5,h6 { font-size:1em; line-height:1.5em; } p,ul,ol,dl { font-size:1em; line-height:1.5; margin-bottom:24px; } ol ol,ul ul { margin:0 0 0 60px; } blockquote { margin: 0 60px 0 45px; border-left: 5px solid #ccc; padding-left: 10px; text-indent: -0.4em; } pre { white-space:pre; white-space:pre-wrap; white-space:pre-line; word-wrap:break-word; }
3/7

/* Anchors */ a { color:#1e80a0; overflow:hidden; border-bottom:1px solid #ddd; text-decoration:none; } a:hover { border-bottom-color:#bbb; }

Follow the DOM


So, while reviewing the DOM setup of the HTML, your CSS default for each module/element section should follow the DOM structure and will be set at this point. For example, if your DOM is setup as so: <html> <head></head> <body> <header> <section> </section> </header> <!-- side modules --> <aside> <!-- aside code will go here --> </aside> <!-- navigation --> <nav> <ul> <li><a href=#><img src=img1.png /></a></li> <li><a href=#><img src=img2.png /></a></li> <li><a href=#><img src=img3.png /></a></li> <li><a href=#><img src=img4.png /></a></li> </ul> </nav> <!-- side modules --> <article> <section> <!-- main header info will go here --> </section> <section id=content> </section> </article> <footer> </footer> </body> </html> Then the CSS will follow the DOM structure and look like so: header { height: 88px; } header section { position: relative; color: #fff; } aside {

4/7

float: right; width: 330px; color: #fff; } nav { margin: 0 345px 20px 0; min-width: 800px; } nav ul { height: 86px; width: 670px; margin: auto; } nav ul li { float: left; height: 64px; width: 64px; background: #fc0; margin: 10px 0 10px 10px; } nav ul li img { width: 64px; height: 64px; } article { background: white url(../img1.png) repeat-y; border-left: none; min-height: 600px; margin: 0 345px 0 0; position: relative; min-height: 600px; border: 1px solid #9a9b9b; -moz-box-shadow: 1px 0 10px 1px black; -webkit-box-shadow: 1px 0 10px 1px black; box-shadow: 1px 0 10px 1px black; } This will allow the CSS to not only mimic the DOM, but also you can implement the general style in each module/element section of the page another level of cascade for the style that is to be applied to the page. Also, consider decoupling the HTML from CSS further and, according to an article by Jonathan Snook, take advantage of child selectors more frequently: nav > ul { height: 86px; width: 670px; margin: auto; } nav > ul > li { float: left; height: 64px; width: 64px; background: #fc0; margin: 10px 0 10px 10px; }

5/7

Class begins
Chris Coyier has written a great article regarding when to use IDs vs. when to use classes - http://csstricks.com/the-difference-between-id-and-class/. My personal approach is to create classes as needed for styling. There are two types of classes that can be created: specific class these classes will be applied to particular area of the site and it is unique to that area. Now if you are thinking if it is unique, then why not apply it to an ID?, you may be right; however, then you will restrict yourself to that section of the application and it may be harder to abstract it later if needed. For example: .arrow-up { width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-bottom: 5px solid black; } .arrow-down { width: 0; height: 0; border-left: 20px solid transparent; border-right: 20px solid transparent; border-top: 20px solid #f00; } .arrow-right { width: 0; height: 0; border-top: 60px solid transparent; border-bottom: 60px solid transparent; border-left: 60px solid green; } .arrow-left { width: 0; height: 0; border-top: 10px solid transparent; border-bottom: 10px solid transparent; border-right:10px solid blue; } utility class these are classes that will be used throughout the site in order to apply certain styles in different areas. These classes can be a style as simple as setting float left or right or it can be something like: .flip-img { -moz-transform: scaleX(-1); -o-transform: scaleX(-1); -webkit-transform: scaleX(-1); transform: scaleX(-1); filter: FlipH; -ms-filter: FlipH; } .float-lft { float: left; }

6/7

A utility class can be applied to any element in the DOM as needed, as you know, multiple classes can be added so multiple functional/utility classes can be added to the same element. For example: <img src=img/img1.png class=flip-img float-lft alt=flipped image example /> Reserve class usage to areas where it cannot be applied to any of the above guidelines. Do not create classes to apply styles to all div elements, for example, and avoid creating a class like this: .div-style { background-color: #fff; margin: 0 10px 5px 0; height: 100%; } The correct approach is: div { height: 100%; background-color: #fff; } /* the margin setting can be set at the DOM level CSS or in a specific class */ Note: The above examples have been borrowed from Chris Coyiers snippets section of the CSS-tricks site (http://css-tricks.com/snippets/).

Conclusion
These rules and guidelines are essential in building a CSS file that is lightweight and highly performant. In part 2 of this post we will review further guidelines in building a well structured CSS file. Stay tuned.

Further Reading
CSS-tricks Comprehensive CSS Principles Nicole Sullivan Object Oriented CSS Jonathan Snook SMACSS Jina Bolton CSS Workflow

ABOUT THIS ARTICLE


I am a native born Iranian and reside in Boston Massachusetts. Husband to a lovely New Englander and father to two lovely girls. In my spare time, I am an enthusiast in all things involving UI development and am lucky enough to be working in that field for clients like VMWare, MIT, and Novartis.

ONLINE RESOURCES How to Write Well-Structured CSS Part II http://innovatorylife.com/2012/05/21/how-to-write-a-well-structured-css-part-ii/


Nick Cooley on Twitter https://twitter.com/nickcooley CSS-Tricks http://css-tricks.com/

http://innovatorylife.com/

@kianoshp

appliness

DONT WORRY, BE APPLI

JavaScript design patterns Part 1: Singleton, composite, and faade

This is the first article in a series about common design patterns used in JavaScript. Design patterns are proven ways of programming to help make your code more maintainable, scalable, and decoupled, all of which are necessary when creating large JavaScript applications, especially in large groups.

Singleton
The singleton pattern is what you use when you want to ensure that only one instance of an object is ever created. In classical object-oriented programming languages, the concepts behind creating a singleton was a bit tricky to wrap your mind around because it involved a class that has both static and non-static properties and methods. Im talking about JavaScript here though, so with JavaScript being a dynamic language without true classes, the JavaScript version of a singleton is excessively simple. Why do you need the singleton? Before I get into implementation details, I should discuss why the singleton pattern is useful for your applications. The ability to ensure you have only one instance of an object can actually come in quite handy. In server-side languages, you might use a singleton for handling a connection to a database because its just a waste of resources to create more than one database connection for each request. Similarly, in front-end JavaScript, you might want to have an object that handles all AJAX requests be a singleton. A simple rule could be: if it has the exact same functionality every time you create a new instance,

ou Playgr

nd

t - JavaScrip - Patterns - Singleton

Difficulty
- rookie - intermediate - expert

Todo list

- faade - isolate

- abstraction

by Joe Zimmerman

then make it a singleton. This isnt the only reason to make a singleton, though. At least in JavaScript, the singleton allows you to namespace objects and functions to keep them organized and keep them from cluttering the global namespace, which as you probably know is a horrible idea, especially if you use third party code. Using the singleton for name-spacing is also referred to as the module design pattern. Show me the singleton To create a singleton, all you really need to do is create an object literal. var Singleton = { prop: 1, another_prop: value, method: function() {}, another_method: function() {} }; You can also create singletons that have private properties and methods, but its a little bit trickier as it involves using a closure and a self-invoking anonymous function. Inside a function, some local functions and/or variables are declared. You then create and return an object literal, which has some methods that refererence the variables and functions that you declared within the larger functions scope. That outer function is immediatly executed by placing () immediately after the function declaration and the resulting object literal is assigned to a variable. If this is confusing, then take a look over the following code and then Ill explain it some more afterward. var Singleton = (function() { var private_property = 0, private_method = function () { console.log(This is private); } return { prop: 1, another_prop: value, method: function() { private_method(); return private_property; }, another_method: function() {} } }()); The key is that when a variable is declared with var in front of it inside a function, that variable is only accessible inside the function and by functions that were declared within that function (the functions in the object literal for example). The return statement gives us back the object literal, which gets assigned to Singleton after the outer function executes itself.

Namespacing with the singleton In JavaScript, namespacing is done by adding objects as properties of another object, so that it is one or more layers deep. This is useful for organizing code into logical sections. While the YUI JavaScript library does this to a degree that I feel is nearly excessive with numerous levels of namespacing, in general it is

2/7

considered best practice to limit nesting namespaces to only a few lavels or less. The code below is an example of namespacing. var Namespace = { Util: { util_method1: function() {}, util_method2: function() {} }, Ajax: { ajax_method: function() {} }, some_method: function() {} }; // Heres what it looks like when its used Namespace.Util.util_method1(); Namespace.Ajax.ajax_method(); Namespace.some_method(); The use of namespacing, as I said earlier, keeps global variables to a minumum. Heck, you can even have entire applications attached to a single object namespace named app if thats your perogative. If youd like to learn a little more about the singleton design pattern as well as its applicability in namespacing, then go ahead and check out the JavaScript Design Patterns: Singleton article on my personal blog.

Composite
If you read through the section about the singleton pattern and thought, well, that was simple, dont worry, I have some more complicated patterns to discuss, one of which is the composite pattern. Composites, as the word implies, are objects composed of multiple parts that create a single entity. This single entity serves as the access point for all the parts, which, while simplifying things greatly, can also be deceiving because theres no implicit way to tell just how many parts the composite contains. Structure of the composite The composite is explained best using an illustration. In Figure 1, you can see two different types of objects: containers and galleries are the composites and images are the leaves. A composite can hold children and generally doesnt implement much behavior. A leaf contains most of the behavior, but it cannot hold any children, at least not in the classical composite example.

3/7

As another example, Im 100% certain youve seen the composite pattern in action before but never really thought about it. The file structure in computers is an example of the composite pattern. If you delete a folder, all of its contents get deleted too, right? Thats essentially how the composite pattern works. You can call a method on a composite object higher up on the tree and the message will be delivered down through the hierarchy. Composite coding example This example creates an image gallery as an example of the composite pattern. You will have just three levels: album, gallery, and image. The album and galleries will be composites and the images will be the leaves, just like in Figure 1. This is a more defined structure than a composite needs to have, but for this example, it makes sense to limit the levels to only being composites or leaves. A standard composite doesnt limit which levels of the hierarchy that leaves can be on, nor do they limit the number of levels. To start things off, you create the GalleryComposite class used for both the album and the galleries. Please note that I am using jQuery for the DOM manipulation to simplify things. var GalleryComposite = function (heading, id) { this.children = []; this.element = $(<div id= + id + class=composite-gallery></div>) .append(<h2> + heading + </h2>);

GalleryComposite.prototype = { add: function (child) { this.children.push(child); this.element.append(child.getElement()); }, remove: function (child) { for (var node, i = 0; node = this.getChild(i); i++) { if (node == child) { this.children.splice(i, 1); this.element.detach(child.getElement()); return true; } if (node.remove(child)) { return true; }

} },

return false;

getChild: function (i) { return this.children[i]; }, hide: function () { for (var node, i = 0; node = this.getChild(i); i++) { node.hide(); }
4/7

},

this.element.hide(0);

show: function () { for (var node, i = 0; node = this.getChild(i); i++) { node.show(); } }, this.element.show(0);

getElement: function () { return this.element; }

Theres quite a bit there, so how about I explain it a little bit? The add, remove, and getChild methods are used for constructing the composite. This example wont actually be using remove and getChild, but they are helpful for creating dynamic composites. The hide, show, and getElement methods are used to manipulate the DOM. This composite is designed to be a representation of the gallery that is shown to the user on the page. The composite can control the gallery elements through hide and show. If you call hide on the album, the entire album will disappear, or you can call it on just a single image and just the image will disappear. Now create the GalleryImage class. Notice that it uses all of the exact same methods as the GalleryComposite. In other words, they implement the same interface, except that the image is a leaf so it doesnt actually do anything for the methods regarding children, as it cannot have any. Using the same interface is required for the composite to work because a composite element doesnt know whether its adding another composite element or a leaf, so if it tries to call these methods on its children, it needs to work without any errors. var GalleryImage = function (src, id) { this.children = []; this.element = $(<img />) .attr(id, id) .attr(src, src);

GalleryImage.prototype = { // Due to this being a leaf, it doesnt use these methods, // but must implement them to count as implementing the // Composite interface add: function () { }, remove: function () { }, getChild: function () { }, hide: function () { this.element.hide(0); }, show: function () { this.element.show(0);

5/7

}, getElement: function () { return this.element; }

Now that you have the object prototypes built, you can use them. Below you can see the code that actually builds the image gallery. var var var var var var var container = new GalleryComposite(, allgalleries); gallery1 = new GalleryComposite(Gallery 1, gallery1); gallery2 = new GalleryComposite(Gallery 2, gallery2); image1 = new GalleryImage(image1.jpg, img1); image2 = new GalleryImage(image2.jpg, img2); image3 = new GalleryImage(image3.jpg, img3); image4 = new GalleryImage(image4.jpg, img4);

gallery1.add(image1); gallery1.add(image2); gallery2.add(image3); gallery2.add(image4); container.add(gallery1); container.add(gallery2); // Make sure to add the top container to the body, // otherwise itll never show up. container.getElement().appendTo(body); container.show(); Thats all there is to the composite! If you want to see a live demo of the gallery, you can visit the demo page on my blog. You can also read the JavaScript Design Patterns: Composite article on my blog for a little more information on this pattern

FAADE
The faade pattern is the final design pattern in this article, which is just a function or other piece of code that simplifies a more complex interface. This is actually quite common, and, one could argue, most functions are actually made for this very purpose. The goal of a faade is to simplify a larger piece of logic into one simple function call. Examples of the faade You just might be using the faade pattern all the time without realizing that youre using any design pattern at all. Just about every single library that you use in any programming language uses the facade pattern to some degreebecause generally their purpose is to make complex things simpler. Lets look at jQuery for an example. jQuery has a single function (jquery()) to do so many things; It can query the DOM, create elements, or just convert DOM elements into jQuery objects. If you just look at querying the DOM, and take a peek at the number of lines of code used to create that capability, youd probably say to yourself, Im glad I didnt have to write this, because it is very long and complex code.

6/7

They have successfully used the faade pattern to convert hundreds of lines of complex code into a single, short function call for your convenience. Finishing up The faade pattern is pretty easy to understand but if you are interested you can learn more from the JavaScript Design Patterns: Faade post on my personal blog.

ABOUT THIS ARTICLE


Joe Zimmerman has been doing web development for 12 years, which may make him sound old, but since he started in middle school, hes still pretty young. HTML and CSS were the coolest inventions ever. In college he was introduced to real JavaScript, starting his full addiction. Now his addiction pushes him to continuously learn more and spread the knowledge to the internet.

ONLINE RESOURCES His blog http://www.joezimjs.com/


Adobe Developer portal http://www.adobe.com/devnet.html Learning JS patterns by Addy Osmani http://addyosmani.com/resources/essentialjsdesignpatterns/book/

http://www.joezimjs.com/

@joezimjs

appliness

DONT WORRY, BE APPLI

Thoughts on Node.js and Express

A while back I posted about how I had begun to see Node in a new light. (Do folks refer to it as just Node or do you always include the JS at the end?) I had some time this week and decided to try building a real, if simple, application. Since I had plenty of data for my blog, I thought a simple blog viewer would be a good application to try building. Here are some random, scattered thoughts on what the process was like.

random thoughts...
First and foremost - I had decided to use Express to build a web application. Express is a Node application framework specifically built for web applications. I had seen Sim Bateman demo this at cfObjective this year and it had looked pretty cool. What I liked right away is how I had complete control over how requests were handled. I was easily able to specify a folder for static crap, like CSS and JavaScript. I then could specify URLs and how to handle them. In ways this is a bit like ColdFusions onRequestStart, but at a much deeper level. You get the ability to say, for example, when a request comes in for /ray/bio, run so and so code. But you can also easily add dynamic patterns as well. If I wanted to match /display/X where X was dynamic, I could set up the code easily enough and Express would automatically give me access to the dynamic portion as a variable. (Before I go any further - let me point out that I may confuse what Express gives you versus what is just plain there in Node. Please forgive me if I make that mistake.)

ou Playgr

nd

Difficulty
- rookie - intermediate - expert

- Node.js - Express - nodemon

Todo list
- blog - build - ponder
by Raymond Camden

Here is an example of all three above. From what I know, the patterns are checked in order of how I coded them. //To use with static crap, like images, jquery, etc app.use(/, express.static(__dirname + /public,{maxAge:86400000})); //default request for home page app.get(/, function(req, res) { blog.getLatestEntries(function(rows) { res.render(home,{entries:rows}); }); }); //blog entry by id app.get(/entry/:id, function(req, res) { blog.getBlogEntryById(req.params.id,function(entry) { res.render(entry, {entry:entry}); },function() { res.writeHead(302, { Location: / }); res.end(); }); }); As I said, the first block handles my static stuff. Ive specified a folder called public and, inside of there, placed my CSS and JS files. Once I drop in a style file, I address it by just pointing the URL to /public/ style.css. The second block handles the home page request. Dont worry about blog just yet, Ill explain it in a bit. But basically, you can see that Im calling for some data and then rendering it. (Again, more on that in a second.) Finally - I added support for loading one particular blog entry. Note that I was able to precisely define a URL pattern of /entry/X. I could have done anything here at all. I love that freedom. To be clear, you can do the exact same in ColdFusion if you add in a URL rewriter like whats built into Apache. But I like having it right here in my application. It makes it a bit easier to mentally grasp what is going on in the application. If you visit my blog often, you know that I use a slightly slicker URL scheme. It took me 5 minutes to add this to my application: //blog entry by fancy SES url app.get(/:year/:month/:day/:alias, function(req, res) { var entryDate = new Date(req.params.year,req.params.month-1,req.params. day); blog.getBlogEntry(entryDate,req.params.alias,function(entry,comments) { res.render(entry, {entry:entry,comments:comments}); },function() { res.writeHead(302, { Location: / }); res.end(); }); });

2/6

Ok, so thats some examples of responding to URLs. Ive got more coming up, but lets talk about something else - rendering the pages. I love JavaScript, but there is no way in heck Im going to build out HTML views in JavaScript. As much as possible Ive been trying to use templating engines lately. As I was researching, I discovered that a library called EJS worked with Express. Hooking it up to Express was rather simple. I told my app I needed EJS and told Express to use it to parse HTML files. Honestly, I dont 100% understand this portion, but it worked: app.engine(.html, require(ejs).__express); app.set(view engine, html); If you look at the app.get(/) block above, you can see where I run res.render(). The first argument is the name of a template to run. By default this will be in a subdirectory called views. The second argument is data Im passing to the view. Here is what home.html looks like - and remember - I did this very fast and kinda ugly. Normally you would have a bit more HTML in there: <h2>Blog</h2> <ul> <%

%>

entries.forEach(function(entry) { var d = new Date(entry.posted); var year = d.getFullYear(); var month = d.getMonth()+1; var day = d.getDate();

<li><a href=/<%= year + / + month + / + day %>/<%= entry.alias %>><%= entry.title %></a> (<%= entry.posted %>)</li> <% }) %> </ul> I am not a fan of the template syntax. Frankly, it felt like I was writing classic ASP. That being said - it did work. Note that Im doing a bit of work to create the fancy URL. EJS supports (I believe) writing your own helper functions. Normally Id have built something to simplify that so that the view had much less logic in it. Just assume that, as my first view, I didnt write this as nicely as I would if given more time. As a comparison, here is the view for an individual blog entry: <h1><%= entry.title %></h1> <%- entry.body %> <% if(entry.morebody) { %> <%- entry.morebody %> <% } %> <% if(comments.length) { %> <h2>Comments</h2> <% comments.forEach(function(comment) { %> <p> Comment posted by <%= comment.name %><br/> Posted at <%= comment.posted %><br/> <%= comment.comment %> </p> <% }) %>
3/6

<% } %>

As I mentioned, Im not really a fan of EJS. There are other alternatives. Right now Im considering Dust, but as I ran into problems with that, I couldnt actually use it. Hopefully at this point you have a rough feel for how Express lets you handle requests and specify views to actually render them. Lets talk about the database layer. After I figured out how to do my views and pass parameters around, I needed to get database support. This is where I got to play around more with NPM. NPM, or the Node Package Manager, is an incredibly powerful tool and probably one of the main reasons Node is so popular. (Other platforms have similar support.) From the command line you can tell Node to get a package (think open source project focused on adding a particular feature) and install it to your system. You can also tell your application itself that it requires a package. So for example, my application needs Express and MySQL support. I can use a special file (package.json) to note these requirements, run one command, and all the supporting libraries just magically come in.

Concluding thoughts
But... this isnt all rainbows and unicorns. When I decided to add RSS support to my application, I used NPM to search for an RSS library. If I remember right, about 30 or so packages showed up. I froze like a deer in headlights. Dont get me wrong, I like options, but I had absolutely no idea which one to pick. This is very much like the problem you may have with jQuery plugins. You can almost always count on jQuery having a plugin to do X, but finding out what the best one is can be a laborious process. I feel like Im going to get some criticism on this, but I do wish people would keep this in mind when praising Node. For me, I picked the package with the name rss just because it had the simplest name. Luckily, the one I chose worked great. I was able to add RSS support soon after: //RSS app.get(/blog.rss, function(req, res) { /* lets create an rss feed */ var feed = new rss({ title: My Blog, description: This is my blog, feed_url: http://www.raymondcamden.com/rss.xml, site_url: http://www.raymondcamden.com, image_url: http://example.com/icon.png, author: Raymond Camden }); blog.getLatestEntries(function(rows) { rows.forEach(function(entry) { feed.item({ title: entry.title, description: entry.body, url: http://localhost:3000/ + entry.posted.getFullYear() + / + ((entry.posted.getMonth())+1) + / + (entry.posted.getDate()) + / + entry.alias, // This can be done better date: entry.posted // any format that js Date can parse. }); }); // cache the xml var xml = feed.xml(); res.send(xml);
4/6

});

});

But it didnt always work out well. I mentioned above that I tried to use another templating engine. The first one I tried, Dust, didnt work because it wasnt supported on Windows. That really surprised me. Shouldnt JavaScript work everywhere? To be fair, the reason the project wasnt supported on Windows was because the author didnt have an environment to test with (and he did the right thing then in marking it not supported), but I ended up getting stuck for a while. So going back to database support, it turns out there are a few options for working with MySQL. Unfortunately, none of them really instilled a great deal of confidence in me. In fact, the solution I went with didnt even support bound parameters! Yes, you could use them in your code, and yes, your data would be escaped, but it wasnt truly using a bound parameter in its communication to the database. And frankly - as much as I like JavaScript, Im not sure how much Id trust a database library written in it. I havent done any performance tests, but out of everything I did, this was the one area that gave me the most doubt. With all that being said, using MySQL was pretty easy. I began by just setting up the connection like so: var mysql = require(mysql); var con = mysql.createConnection({ host:localhost, user:root, password:passwordsareforwimps, database:myblog_dbo }); con.connect(); I then created a module called blog that would handle my service layer. Since I had a con object that represented my database connection, I exposed an API where I could pass it in to the blog: var blog = require(./blog.js); blog.setConnection(con); Here then is my blog module. A real blog engine would have quite a bit more of course but you get the idea. var CONN; exports.setConnection = function(con) { CONN=con; } exports.getLatestEntries = function(cb) { CONN.query(select id, title, alias, posted from tblblogentries order by posted desc limit 0,10, function(err, rows, fields) { cb(rows); }); } exports.getBlogEntryById = function(id,success,fail) { CONN.query(select id, title, body, morebody, posted from tblblogentries where id = ?,[id], function(err, rows, fields) { if(rows.length == 1) success(rows[0]); else fail(); }); } exports.getBlogEntry = function(date,alias,success,fail) { var year = date.getFullYear();

5/6

var month = date.getMonth()+1; var day = date.getDate(); CONN.query(select id, title, body, morebody, posted from tblblogentries where year(posted) = ? and month(posted) = ? and dayofmonth(posted) = ? and alias = ?, [year,month,day,alias], function(err, rows, fields) { if(rows && rows.length == 1) { exports.getCommentsForBlogEntry(rows[0].id, function(comments) { success(rows[0],comments); }); } else fail(); }); } exports.getCommentsForBlogEntry = function(id,success) { CONN.query(select id, name, email, comment, posted, website from tblblogcomments where entryidfk = ?, [id], function(err, rows, fields) { if(!rows || !rows.length) rows = []; success(rows); }); } So what do I think? I love it. Once I got my environment running (and be sure to use nodemon to make reloading automatic) I was able to rapidly build out a simple application. I loved the level of control I had over the request and how quick it was to get up and running. I didnt love the fact that the quality wasnt quite consistent across various modules. p.s. One more code snippet. I demonstrated the RSS support above. But I also built in a quick JSON view as well. It was incredibly difficult. Honest. This took me hours to write. (Heh...) //API app.get(/entries.json, function(req, res) { blog.getLatestEntries(function(rows) { res.writeHead(200, {Content-Type:application/json}); res.write(JSON.stringify(rows)); res.end(); }); });

ray on github
You can get Rays gists on GitHub.

https://gist.github.com/cfjedimaster

appliness

DONT WORRY, BE APPLI

iOS Safari Web Apps Templates and HowTos


close to native

GREG WILSON SHARES WITH US HOW TO BUIlD A FIRST CLASS EXPERIENCE FOR IOS WEB APPS.

An iOS web application uses HTML/CSS/JS to deliver a iOS experience that looks and behaves like a native iOS application. If done correctly, the user cant tell that its not a normal app. Although the capabilities are limited, it can be a great solution for many apps where going through the normal iOS app store is overkill or not practical.

Creating iOS web apps can be very error prone. The size requirements for icons and splash screens are odd and there are a few things that are non-obvious (e.g., the iPad landscape splash image is actually a portrait-shaped image but has its contents rotated; Retina displays reserve 40 pixels for the status bar while non-retina reserve 20 pixels, etc.). Also, if you screw something up, you get no errors. It just simply doesnt work leaving you to guess/hack.

What started as a 15 minute attempt to get icons and splash screens working for my web app re-

ou Playgr

nd

t - JavaScrip - Web app - XML

Difficulty
- rookie - intermediate - expert

Todo list

- manifest
by Greg Wilson

- get icons

- phosothop

sulted in a couple of hours of what felt like pure hacking. Many of the online resources (including Apples!) were out of date and didnt include information on handling iPad retina icons/images. I decided to share my results to hopefully spare others from the frustrating experience.

fun facts
iPhones dont need a landscape splash screen. The apps always display a portrait splash image regardless of orientation. The app itself will turn landscape as expected, but it always launches as portrait. The iPad landscape splash screen is a weird thing -- it actually requires a portrait-shaped image with rotated content so if you view it in any image viewer, it will appear 90 degrees rotated. (see the sample images in the repo) My examples use square images and allow the device to add the rounded corners and the lighting highlights. I think it looks far better than any attempt I would make. See the Apple docs on configuring web apps for information on how to precompose your icons rounded corners and reflections.

webapp1-plain
The webapp1 template is a simple web app that has icons and splash screens that has been tested on an iPhone 3Gs, iPhone 4, iPhone 4s, iPad 1, iPad 2, and the new iPad (retina). You can test webapp1 by pointing your iOS Safari browser to

http://gregsramblings.com/webapp1
click the share button and select Add to Home Screen. You should see the icon and you should see splash screens when you launch it. Here is the code of this web app template: <html> <head> <title>WebApp Title</title> <meta name=viewport content=user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0/> <!-- Make this thing web-app capable --> <meta name=apple-mobile-web-app-capable content=yes/> <!-- iPhone non-retina 57x57 --> <link rel=apple-touch-icon href=icon57.png/> <!-- iPad non-retina 72x72 --> <link rel=apple-touch-icon sizes=72x72 href=icon72.png/> <!-- iPhone retina 114x114 --> <link rel=apple-touch-icon sizes=114x114 href=icon114.png/> <!-- iPad retina 144x144 --> <link rel=apple-touch-icon sizes=144x144 href=icon144.png/> <!-- iPhone standard resolution 320x460 (landscape not needed because all
2/4

web apps start portrait on iPhone) --> <link rel=apple-touch-startup-image href=splash-320x460.jpg media=(device-width: 320px) /> <!-- iPhone high resolution (retina) 640x920 pixels (landscape not needed because all web apps start portrait on iPhone) --> <link rel=apple-touch-startup-image href=splash-640x920.jpg media=(device-width: 320px) and (-webkit-device-pixel-ratio: 2) /> <!-- iPad Portrait 768x1004 --> <link rel=apple-touch-startup-image href=splash-768x1004.jpg media=(device-width: 768px) and (orientation: portrait) /> <!-- iPad Landscape 748x1024 (yes, a portrait image but with content rotated 90 degrees - allows 20px for status bar) --> <link rel=apple-touch-startup-image href=splash-748x1024.jpg media=(device-width: 768px) and (orientation: landscape) /> <!-- iPad retina Portrait 1536x2008 --> <link rel=apple-touch-startup-image href=splash-1536x2008.jpg media=(device-width: 768px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 2) /> <!-- iPad retina Landscape 1496x2048 (yes, a portrait image but with content rotated 90 degrees - allows 40px for status bar) --> <link rel=apple-touch-startup-image href=splash-1496x2048.jpg media=(device-width: 768px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 2) /> <style> /* The following CSS prevents Safari from changing the font size when the device is rotated - you may or may not need this */ body, html { -webkit-text-size-adjust: 100%; /* prevents text size from changing on orientation change */ } </style> </head> <body> <h3>iOS Safari Web App Template #1</h3> <ul> <li><a target=_blank href=https:/ /gregsramblings.com>Blog Post</a> </li> <li><a target=_blank href=https:/ /github.com/gwilson/iOSWebAppTem plates> Github project</a></li> <li><a target=_blank href=http:/ /developer.apple.com/library/ safari/#documentation/appleapplications/reference/SafariHTMLRef/Articles/ MetaTags.html>iOS Safari Meta tag docs</a></li> <li><a target=_blank href=http:/ /developer.apple.com/library/ safari/#referencelibrary/GettingStarted/GS_iPhoneWebApp/_index.html>Getting Started with iOS Web Apps</a></li> </ul> Tap the share button in Safari and select Add to Home Screen to see the re sults. You should see the correct icon and the correct splash screen when you launch the web app. </body> </html>
3/4

webapp2-add2home
This is the same as webapp1 but adds Matteo Spinellis add to home script functionality that prompts the user to add the web app to their home screen with simple and clear instructions. See http://cubiq.org/add-to-home-screen for the latest script, docs and other information. You can test webapp2 by pointing your iOS Safari browser to

http://gregsramblings.com/webapp2
- you should see a popup that points to the share button explaining how to add the app to the home screen. more coming soon including offline support

templates on github

You can get all the templates on GitHub. More coming soon including offline support:

https://github.com/gwilson/iOSWebAppTemplates

ABOUT THIS ARTICLE


Greg is a Developer Evangelist at Adobe Systems focusing on the use of Adobe technologies in enterprise applications. Technologies include HTML, JavaScript and related technologies, Flex, AIR, data services, digital publishing, and anything mobile, tablet and desktop app development related.

ONLINE RESOURCES Gregs blog http://gregsramblings.com/


Add to home screen library http://cubiq.org/add-to-home-screen HTML & Adobe http://html.adobe.com

http://gregsramblings.com/

@gregsramblings

appliness

DONT WORRY, BE APPLI

Infinite timeline scrolling chart

mihai corlan explains how to develop an advanced data visualization component.

A while ago, my fellow evangelist Christophe Coenraets created a cool desktop application (and later a mobile version) as a concept of how an application used by sales people could look in the 21st century. Part of that app was a nice chart that allowed you to quickly see all the projects while swiping back and forth on the timeline. Now, that little piece was developed using the Flex framework. In a moment of complete boredom I decided to recreate the chart part using HTML, CSS, and JavaScript. And to make things more interesting, I wanted the same code to run on desktop and mobile devices (tablets and smartphones). Here is a screenshot of Christophes original app:

ou Playgr

nd

Difficulty
- rookie - intermediate - expert

- SVG t - JavaScrip - Layers

Todo list

- interactivity

- get data - draw shapes

by Mihai Corlan

And here is my interactive HTML sample:

features
This chart could be used to visualize sales leads or accounts. Imagine a data structure like this: //SAMPLE DATA [ {date, probability, revenue, account, project-name}, {date, probability, revenue, account, project-name}, ... ] How would you represent such a structure in a meaningful way? This chart uses three pieces of information to represent the data: - The date of the project. This is used to position each circle on the horizontal axis. - The probability of the project. This is used to position the circles on the vertical axis. - The revenue of the project. The bigger the revenue, the bigger the circle diameter.
2/6

You can scroll the chart on the horizontal axis, the timeline axis (the time is represented as months). By default you see a little bit more than 3 months. If you want to change this, just grab one of the vertical lines and drag to left (if you want to have more months), or to the right (if you want to have fewer months). If you touch (or move your mouse over) one of the circles you will see a tooltip that displays additional info. Thats it. Although it may look simple, I think that it does a good job at representing the data. Add to this the interactivity layer which I think that feels quite natural, especially on a device like iPad, and you have a winner.

How it works
If you want to build a chart using web standard technologies, then most likely you will be using one or a combination of these: the canvas element, SVG and other HTML elements (could be divs or images). If you want to have some sort of interactivity, like maybe being able to click on something drawn on the chart then SVG is the best choice (you can draw shapes while being able to listen for events for each shape) and canvas is the worst option (you work with pixels so there is no built-in way of telling on what shape a user clicked). However if you want to run the code on desktop and mobile browsers, then SVG is not the best option anymore. On some mobile platforms, SVG is not supported at all and on most mobile platforms, it is not hardware accelerated (I will come back to the importance of being hardware accelerated). So SVG was gone which left me with Canvas and HTML elements. And actually this is how I built the chart: a canvas element for drawing the chart axes and labels and on top of it a number of divs for rendering the chart data (circles) and supporting the interactive part of the chart. Here is a diagram of how the parts work together: Here are some explanations about these layers: 1. The first element is a canvas. This is used for drawing the axes and labels plus the vertical and horizontal lines 2. On top of the canvas element there is a div (absolute positioning) that acts like a mask (overflow is set to hidden). This div covers just the plotting area of the canvas (so the labels drawn on the canvas are outside of the div). The handlers for dragging the timeline are registered on this element. 3. Next, there are a number of divs added to the previous div. These divs are kept in synch with the vertical lines drawn on the canvas (position and height). These divs can be dragged in order to change the timeline density (to display more or fewer months). 4. Finally, the data are drawn using a bunch of div elements (with border-radius to make them look like a circle) and all of these elements are added to the mask div.
3/6

The algorithm that draws the data, scrolls the chart, and changes the timeline density is pretty simple. Basically, when the chart is drawn for the first time, I save the first Date (the one at the chart origin) that is part of the current view (I will call this the origin date) and the number of pixels for one day. From there on, every time the chart is scrolled, all I have to do is to adjust the origin date based on the amount of scrolling (number of pixels), scrolling direction (adds/subtracts days), and the number of pixels for a day. When the chart density is changed, I recalculate the number of pixels taken by a day and the new density (the number of months to be displayed in the same time).

Extending the chart


If you want to use this chart, chances are that you would want a different way to represent the data. The good news is that I built the chart with extensibility in mind (though I have to say that this part could be improved). There are a number of methods you will need to touch. The most important one is plotData(). This method is responsible of drawing the data (the circles/divs). This is its signature: /** * Draws the data. * @param div to be used as the parent * for drawing the data * @param currentDateInterval current date * interval {sDate: Date, eDate: Date, xDates: Array} * sDate and eDate represent the first and last date * part of the current chart * @param pxPerDay pixels for one day * @param dataProvider {array} the data provider */ function plotData (chartDiv, currentDateInterval, pxPerDay, dataProvider) { ... } Those four arguments are all you need to draw the data. If you want to overwrite this method, you can pass to the constructor your custom plotData() function as the third argument. plotData() is the main area where you want to first take a look if you want to customize the chart. Next in line are the method responsible for displaying the tooltip (obviously your data will be different so the tooltip content will differ too) and the algorithm for drawing the vertical axis (the example uses percentages for the Y axis; again your need may be different).

4/6

Lessons learned
The first lesson I learned (not that I didnt know :D) is that even the most performant mobile devices are miles away of desktops. Then, mobile browsers are not equal to desktop browsers (some versions ). There are differences in capabilities. For example, canvas is not hardware accelerated on all Android phones while the desktop WebKit-based browsers have support for hardware acceleration for canvas. Because of all this, you have to test your code as quickly as possible on mobile devices. This way, you identify the performance issues sooner than later.

debugging
Debugging your code on mobile devices can be frustrating. Most of the development time for this example was spent on desktop. The last feature I added was the ability to change the timeline density. On the desktop it worked perfectly. On my iPad and Nexus phone, it didnt. The console provided by Safari mobile console and weinre were useless. I found the problem in less than a minute thanks to my Nexus phone and Chrome for Android I used the USB debugging feature. Needless to say that once I got the code running on my Nexus, it was running on my iPad too. I think that having access just to JavaScript Console on a mobile device is not enough. If you do serious web development for mobile then you should get yourself a device that gives you JavaScript debugging and the rest of the web inspector tools. As far as I know, right now only Chrome for Android and PlayBook offer this. Get yourself one of these and you will be happier :). Another lesson that I learned the hard way is working correctly with touch events. If your application relies on the touchstart, touchmove, touchend events, then you have to fire an event.preventDefault() in the touchstart and touchmove event handlers. Failing to do this, youll be waiting the whole day for the touchend event to be triggered it will never happen. Another benefit is that you dont get the element selected when you move it around (I mean the element is not highlighted or whatever you want to call this default browser behavior). As I was testing the scrolling performance on iPad and Nexus, I was initially disappointed by the performance. I mean I was only able to scroll couple of pixels. Once I added the preventDefault() calls everything worked fine. When you have code that runs on desktop and devices you have to be careful with the size of the UI elements. Make them too small and it will be hard to be used. This is exactly what happened to me. The width of the vertical lines for adjusting the timeline density where set to 4 pixels. On a desktop it was more than enough to be able to click and drag. On my phone it was almost impossible. Making them 22 pixels wide solved the problem. The last thing I did was to preserve resources when it made sense to reuse them. As you know it is pretty expensive to add and remove HTML elements (in terms of time, which translates in frames per second, which translates in UI responsiveness). In this application, I cache the divs used for plotting the data or vertical lines when I dont need them. This means that even if there are 1,000 circles the maximum number of divs is equal to the maximum number of circles at one point. As the chart is scrolled to the left or to the right, the circles that are getting out of the view go back into the cache and the ones that are coming into the view are rendered reusing divs from the cache (if the cache is empty a new div is created).

5/6

getting the code


All of the code is hosted on GitHub. You can take the code, fork it, and do whatever you want from here. https://github.com/mcorlan/InfiniteTLChartJS If all you want is to take a quick drive test, visit this link. http://corlan.org/downloads/_html/InfiniteTLChartJS/

Conclusion
Building interactive experiences that run well across devices using web standard technologies is possible today. Or to be more precise, if you want to write once and run everywhere without dropping CSS/HTML capabilities, then you will have to target modern browsers. Most of the times you will find yourself using a mix of techniques when building code that runs on desktop and mobile devices, techniques that represent the common denominator between the mobile and desktop browser capabilities. If you take my code and build something new with it, Id be happy to see the result :)

ABOUT THIS ARTICLE Mihai Corlan has been working for Adobe since 2006. Since 2008 he has been working as a developer evangelist for Adobe. His current role is worldwide web developer evangelist. This means he writes code, he writes articles, and he speaks.
http://corlan.org/ @mcorlan

ONLINE RESOURCES Mihais blog http://www.corlan.org


Christophe Coenraets blog http://coenraets.org/blog/ About data visualization http://www.tricedesigns.com/2012/05/02/data-visualization-withweb-standards/

appliness

DONT WORRY, BE APPLI

Multimedia Troubleshooting

IAN is an html5 multimedia expert. He lists in this article the top 10 gotchas that you may encounter while working with multimedia APIs: browser support, mime types, file conversion, attributes, volume control, plugins required, fullscreen videos, internet explorer 9 behavior, webcams, microphone access... everything is covered.

multimedia and classic gotchas


While I was researching HTML5 multimedia-related topics for my book, HTML5 Multimedia: Develop and Design, I noticed a number people struggling to get HTML5 audio and video working in different scenarios. From Twitter to Stack Overflow, the same questions kept cropping up, so Ive put together a list of the most common problems (and some not so common) and their solutions (if there is one!). In most cases, the problems and solutions apply to both audio and video. Ill note when something is specific to one or the other. Before I go any further, if you arent aware of how you can actually go about adding audio and video to your website via HTML5, you can read a number of other articles on HTML5Doctor.com to get you up to speed. Tom Leadbetter covered the video element, and Mark Boas covered native audio in the browser and HTML5 Audio The State of Play. In addition, I covered the same topics, video and audio, as part of a series of articles in the May issue of Appliness.

ou Playgr

nd

Difficulty
- rookie - intermediate - expert

- Audio - Video - Disco

Todo list

- attributes - codec

- getUserMedia

by Ian Devlin

1
Audio

BROWSER SUPPORT

This is one of the first things you should check: Does the browser youre using actually support the type of media file youre trying to play? Its simple enough to forget which browsers support which file types, so Ill refresh your memory here.

Firefox supports Ogg Vorbis and WAV Opera supports Ogg Vorbis and WAV Safari supports MP3, AAC, and MP4 Chrome supports Ogg Vorbis, MP3, WAV, AAC, and MP4 Internet Explorer 9+ supports MP3, AAC, and MP4 iOS supports MP3, AAC, and MP4 Android supports AAC and MP3 In order to support all of the browsers mentioned above, its advisable to serve your audio file in Ogg Vorbis, and MP3. For example: <audio controls> <source src=myAudio.ogg type=audio/ogg> <source src=myAudio.mp3 type=audio/mp3> </audio> VIDEO Firefox supports Theora Ogg and WebM Opera supports Theora Ogg and WebM Safari supports MP4 Chrome supports Theora Ogg, MP4, and WebM Internet Explorer 9+ supports MP4 and WebM (requires a plugin) iOS supports MP4 Android supports MP4 and WebM (2.3+) In order to support all of the browsers mentioned above, you should serve your video file in both WebM and MP4 using the source element. For example: <video controls> <source src=myVideo.mp4 type=video/mp4> <source src=myVideo.webm type=video/webm> </video>

MIME TYPES

Even if you have the correct media file for the browser, its possible that your server doesnt have the correct MIME type set up. MIME types tell the server how to handle the different file types. If youre using something akin to Apache and you know your stuff, head to the .htaccess file and add the following for

2/5

audio support: AddType audio/ogg ogg AddType audio/ogg oga AddType audio/wav wav AddType audio/mpeg mp3 AddType audio/mp4 mp4 AddType audio/mp4 mpa And similarily for video support: AddType video/webm webm AddType video/mp4 mp4 AddType video/ogg ogg AddType video/ogg ogv If you dont have access to your servers .htaccess file, your control panel should have an option somewhere that allows you to view and add MIME types. If you have a Windows server, then you may need to add the MIME types to IIS, either using the IIS Manager or in the web.config file.

FILE CONVERSION

Its quite possible that a client has sent you a media file and youve determined its MIME type from its file extension. Its possible, however, that the file wasnt encoded correctly. It could, for example, be a perfectly valid MP4 file but, for some reason, some browsers have trouble playing it. If this happens, youre better off encoding the file yourself using a tool such as Miro Video Converter or Media Converter so you can be sure of the correct encoding. Additionally, some files, especially MP4 files, dont always play in a browser that is supposed to support them. This is due to the fact that MP4 (also known as H.264) files can be encoded according to different profiles. If the file in question is encoded in a profile that the browser doesnt support then, naturally, it wont work. If this happens to you, try to ensure that the file is encoded according to the Baseline profile which is more likely to be supported than any of the more advanced ones. In my experience, using a tool like Miro ensures that the MP4 file will work just fine in supporting browsers. If you need to support Firefox 3.6 and lower, youll also need to convert your audio files to Ogg and add them as an extra <source> for the <audio> element.

MP4 Files That Dont Start Playing Until Fully Downloaded

Usually HTML5 audio and video players will allow the user to start playing a media file before it has fully downloaded (as long as it actually has something to play!). Sometimes this isnt the case with an MP4 file, where the browser waits to download the entire file before making it available to play. This is due to an encoding issue. Sometimes MP4 files are encoded with the file index (which contains information on the file such as its duration) placed at the end of the media file rather than at the beginning. This index contains the metadata that the browser requires in order for it to offer progressive download. If this index is at the end, it knows nothing at all about the file and, therefore, has to wait until it receives the index. If this happens to you, theres a simple fix called the QTIndexSwapper by Renaun Erickson that you download to your computer and run on the file that simply moves the index to the start of the file and saves it.
3/5

Getting Your Attributes Right

This might seem a little obvious, but its amazing how many questions I see on Stack Overflow where people are wondering why a certain function isnt working when theyre using attributes that no longer exist. A prime example of this is the autobuffer attribute on both the <audio> and <video> elements, which was replaced by the preload attribute as far back as February 2010. People seem to forget that HTML5 is not yet finalised (although large parts of it are quite stable) and that anything you read might be out of date. Its worth checking the W3C HTML5 specification and also When Can I Use? to view browser support.

Volume Control in Firefox 11+

This is a problem that has cropped up recently. Some of you may have noticed that the volume controls have disappeared from the audio player in Firefox 11+. True, you can mute it, and the volume controls are still controllable via the keyboards up and down keys, but the volume slider itself was removed due to two bugs. I assume this will return in the future but, for now, in case you were wondering what happened to them, its not your fault. (You can, of course, use the Media API to build your own set of custom controls.)

Plugins Required

One of the biggest selling points of HTML5 audio and video is that no third-party plugins such as Flash are required in order to play multimedia files, as long as the browser in question supports it. Unfortunately, this is not strictly true, as both Internet Explorer (9+) and Safari do require Microsoft Media Player and Apple QuickTime, respectively, to be installed in order for them to be able to play HTML5 audio and video files.

Video and Fullscreen

An oft-requested requirement for HTML5 video is the ability to play in fullscreen mode. The HTML5 specification has nothing to say on this, but a separate specification for a Fullscreen API is currently under work, with experimental versions available in some of the major browsers. The following browsers go some way to supporting the Fullscreen API, albeit using their own vendor specific versions: Chrome 19+ Firefox 12+ Safari 5.1+
4/5

There is also the screenfull.js JavaScript polyfill that enables this functionality for a limited number of browsers.

Internet Explorer 9+ Ignores Your Poster Image

If you have a HTML5 video defined with a poster image (using the poster attribute), you might be surprised when Internet Explorer 9 completely ignores it unless you have set the preload attribute to be none. Since Internet Explorer was one of the last browsers to support HTML5, we all grew accustomed to the other browsers treatment of the poster attribute: if its specified, display that image until the user starts to play the video. Internet Explorer 9 doesnt do this. It only displays the image contained within the poster attribute if it has nothing else to show, so if the first frame of the video has been loaded (with preload set to auto the default value or metadata), then it uses this regardless of whats in the poster attribute. This appears to be a case of Internet Explorer interpreting the specification in its own way and doing something different to all other browsers. Internet Explorer 10 also currently exhibits the same (mis)behaviour.

10

Accessing Webcams and Microphones

The ability to access peripheral devices such as microphones and webcams was always in the minds of the HTML5 specification writers when they added the <device> element. This has since been removed and replaced with the more thorough getUserMedia API, which allows access to such media devices. The API itself is easy to use, but browser support is currently quite limited. Opera is currently the only browser with an implementation, supporting only video, but you can already see what it can do. Internet Explorer 10 will follow suit, and it will soon appear in Firefox Nightly.

SUMMARY
This ends my round up of gotchas that you may encounter when working with HTML5 audio and video. Of course, it doesnt cover everything, and Im sure there are issues that you may have come across that havent been mentioned here. If you have, please do add them in the comments, below my original blog post along with their solution if possible, or if not, I or one of the other HTML5 Doctors will try to help.

ABOUT THIS ARTICLE


Ian Devlin is an Irish web developer, blogger, and author who enjoys coding and writing about emerging web technologies such as HTML5 and CSS3. In addition to front-end development, Ian also builds solutions with back-end technologies such as .NET and PHP. He has recently written a book titled HTML5 Multimedia: Develop and Design.

ONLINE RESOURCES HTML5 Doctor website http://html5doctor.com/


Ians blog http://www.iandevlin.com/blog GetUserMedia API http://dev.w3.org/2011/webrtc/editor/getusermedia.html

http://www.iandevlin.com/blog

@iandevlin

appliness

DONT WORRY, BE APPLI

Using HTML/JS Templates to Generate More Than Just HTML

In this article, andrew discusses how to use html and javascript templates to generate html and data structures to pass to applications such as livecycle.

using templates to generate xml


I recently worked on an application that was used to demonstrate the process of capturing data from a mobile application created using PhoneGap, and pushing that data into a LiveCycle servers workflow engine. Since my data was being captured and stored locally as JSON objects, I asked myself why cant I use a template to generate the XML for sending to LiveCycle? It turns out you can, and its not that hard at all. The entire mobile experience was created using HTML, CSS, and JavaScript. Since the prototype application was intended to work in offline scenarios, it didnt push to a server automatically. Rather, you had to manually push data to LiveCycle once you were on the network via a REST API service invocation. Since I couldnt guarantee that the device was on the network, all data was collected on the client using a standard HTML form and data was saved locally as JSON strings using PhoneGaps local storage imlementation. Since the data was stored with plain old JSON, it is really easy to manipulate using JavaScript. You can transform it into HTML, raw text, XML, or whatever format you want. To present the data back to the user within the application experience, I took advantage of the templating features from underscore.js. Templating

ou Playgr

nd

- PhoneGap - LiveCycle - JSON

Difficulty
- rookie - intermediate - expert

Todo list
- store - display - transform
by Andrew Trice

in HTML/JS apps enables you to separate dynamically-generated HTML structure from your application logic, and it keeps your JavaScript code clean without having to manage lots of string concatenation. I used these templating features to generate all views within the application, including tabular data views and even HTML forms that auto populated with data. Basically, anywhere there was an HTML-based view, I used a template to generate that HTML. The REST API for LiveCycle expects you to pass the information for your form(s) in XML formats that match the information captured within the workflow process. The exact structure of the XML depends upon how the LiveCycle server/document workflow is configured, but in any case, it is still XML. You can use templates to generate this XML, or any text-based structure for use in any service call. This technique can work in many scenarios, and with any endpoint whether it is REST, SOAP, some other JSON string format (transformed), or something entirely different altogether. Templates enable you to cleanly generate text strings from JSON objects. Heres basically how I used templating: JSON to HTML I used templates to generate my HTML views within the application. JSON to XML I used templates to generate the XML structure that was passed as parameters to the LiveCycle servers REST API. Below is a really simple example showing how you can use templates to transform JSON objects for use within your applications. It uses jQuery for quick and easy DOM manipulation, Twitter Bootstrap for UI styling, and underscore.js for templates. Click on the first button to display a string version of the JSON object using JSON.stringify() (without any templating), click the second to display a HTML table that was generated using a template, and click the last button to generate an XML string using a template.

2/4

This example is intended to be pretty simple all of the JavaScript and the templates are included in one file, and it only demonstrates how to generate XML strings. Im not posting it to a server in this example. Once youve generated the XML string, you could do anything with it, I posted it to the LiveCycle server using a simple jQuery $.ajax() call. You can download the full source for this example here.

Raw JSON
Lets first examine the raw JSON object. It is an array that contains several objects. var rawData = [ {id:1, firstName:Homer, lastName:Simpson, email:homersimpson@fakee mail.com, phone:555-123-1234}, {id:2, firstName:Bart, lastName:Simpson, email:bartsimpson@fakeemail. com, phone:555-123-2345}, {id:3, firstName:Marge, lastName:Simpson, email:margesimpson@fakee mail.com, phone:555-123-3456}, {id:4, firstName:Lisa, lastName:Simpson, email:lisasimpson@fakeemail. com, phone:555-123-4567}, {id:5, firstName:Maggie, lastName:Simpson, email:maggiesimpson@fakee mail.com, phone:555-123-5678} ];;

Generating HTML
Next, lets examine how the HTML structure gets generated. The generateHTML() function uses an underscore.js template to generate an HTML string, which gets loaded as the content HTML of the output div. function generateHTML() { var data = { target:rawData }; var template = _.template( $(#tpl-html).text() ); $(#output).html( template(data) ); }; The HTML table is generated using the following template. Notice that underscore.js template uses a JSP-like syntax for injecting values. This template will loop over the array content and will generate a table row for each entry. <div class=well> <table class=table> <thead> <tr> <th>ID</th> <th>Name</th> <th>Email</th> <th>Phone</th> </tr> </thead> <tbody>

3/4

<% _.each( target, function(i) {%> <tr> <td><%= i.id %></td> <td><%= i.lastName %>, <%= i.firstName %></td> <td><%= i.email %></td> <td><%= i.phone %></td> </tr> <% }); %> </tbody> </table> </div>;

Generating XML
You can generate XML strings for use in REST endpoints using this exact same approach. Look at the generateXML() function below. It uses a template to render the exact same data into an XML string: function generateXML() { var data = { target:rawData }; var template = _.template( $(#tpl-xml).text() ); var xml = template(data); }; The only real difference between these two examples is the template. The template used to generate the XML string is displayed below: <data> <% _.each( target, function(i) {%> <entry> <id><%= i.id %></id> <name> <last><%= i.lastName %></last> <first><%= i.firstName %></first> </name> <contact> <email><%= i.email %></email> <phone><%= i.phone %></phone> </contact> </entry> <% }); %> </data>; Again, you can download the full source for this example here.

HARDY

VINCENT
We are moving towards a more graphical & more expressive Web.

SHAPING THE WEB

1/9

Hi Vincent, thank you so much for taking time out of your schedule to speak with us. Could you give us a little introduction of yourself? What are you doing these days? What is your passion?

Hi, thanks for talking with me! I am a French-born Californian who started working on distributed computing before realizing my heart was in graphics, animation and the Web. I grew up on math and technology because my mother was a math teacher and my dad was a researcher at the France Telecom R&D center in my hometown, Lannion (Brittany, France). I also grew up on European graphic novels like Asterix, Tintin and Spirou & Fantasio. Later on, I studied telecommunications in Paris where I met my wife, Anne. We have two children whom we encourage to develop their creative skills (creative writing, drawing and painting). My personal passions are running, yoga and graphic novels (I have not fully grown up maybe). My technical passions are the Web, graphics and animation. I believe the most important work at hand is to make technology accessible to more people and remove the barriers that make it hard to use. I am the director of the Adobe Web Platform group. Our team is an incredible mix of talents with people expert in graphic design, JavaScript programming, WebKit development, mobile development, different aspects of the Web formats and web stack, and we use very agile development methods. This wide variety of skills and practices makes it a wonderful team to work with. We contribute to W3C standards and open source efforts, and we work closely with various tools teams (see more details at html.adobe.com).
Can you give us a behind the scenes perspective on what the W3C SVG Working Group is and how it works?

I am less involved in the SVG Working Group than I was several years ago. That group is responsible for defining and evolving the Scalable Vector Graphics (SVG) format. It is a very pleasant group to work with. In the past, I got the chance to work with great people like Jon Ferriaolo (ex-Adobe, now at IBM) or Jerry Evans (from Sun Microsystems) from whom I learned a lot. Their depth of technical knowledge, ability to explain difficult technical concepts and sheer work power was inspiring. When I participated, a lot of the work went towards reporting issues found when implementing the draft SVG 1.0 specification in the Batik open source project (this is a Java-based toolkit to view, render and transcode SVG). The discussions were very technical: we reported issues in the form of specific examples with questions and alternative proposals, and then worked with the group to come to a resolution. This was nice because the skeleton of the specification was stable and we were hammering out the features, making sure they were interoperable (for example, we did a lot of work around filter effects to make sure the algorithms and descriptions in the specification were detailed and specific enough). Nowadays, other members of our group are participating in the SVG efforts and the focus is currently on SVG 2.0 and a fair amount of coordination with the CSS working group around topics such as filter effects, animation, transforms or masking and compositing. Our team participates in different capacities, either as co-editors of some of these efforts, as reviewers or as contributors to the test effort.

2/9

There is less magic or behind the scenes things in Working Groups than I think people imagine. For example, meeting minutes are posted to the public mailing list: things are happening in the open. The work is very technical, with arguments about the merits of proposals and options for features. Our team at Adobe blogs about the work with various working groups and specifications at https://blogs.adobe.com/webplatform/.
How do you ensure that a browser vendor correctly implements a W3C specification?

The W3C process comes to the rescue! There is a track for W3C specifications which is called the recommendation track. The specification goes to an initial first published working draft (FPWD), then iterates through multiple working drafts (WD) while stabilizing and refining the features. When it is solidified and the group has reached consensus, the specification is ready to go to the last call (LC) stage, which is the last chance for the group and others to provide feedback before the specification is basically frozen and moves to Candidate Recommendation (CR). To exit CR, the specification needs to have an associated test suite and two interoperable implementations for each feature. So this last step in the process is key in getting implementations and creating interoperability among the features. At Adobe, we think the specification tests are really important and we also believe (as do many others) that more should be done in that area. We have organized an event called Test the Web Forward (http://testthewebforward.org) to get even more tests contributed to the W3C test suites, in particular in CSS and SVG. We feel that this is a great way to get better and more interoperable implementations. By documenting the process for contributing tests and encouraging people to submit tests, we feel that people have an actionable way to help move the Web forward and do something about the issues they are facing.
Is SVG still a strategic specification for the web? What are the use cases for it?

SVG is definitely a strategic component for the Web! A vector format for graphics allows authors to describe images in terms of their components: shapes, text, images, effects, painting properties - instead of being limited to a set of a pixels. The beauty of a vector format is that it can be drawn at any resolution with high quality. With the rise of retina display and very rich rendering screens across all kinds of devices, it becomes more and more important to have vector formats for images rather than pixelbased image formats. For most kinds of logos and icons, SVG would be significantly smaller and more robust to render across these screens than other kinds of images. But SVG is also the underpinning data visualizations, often combined with JavaScript frameworks such as d3.js. SVG brings graphical elements to HTML in a manner that is consistent with HTML. For example, elements can be styled in a way similar to DOM APIs (even though there are additional styling properties). Interactivity, CSS animations and transitions also apply. Also, and I think this is very important, SVG can be inlined in HTML content, so it is really an integral part of the authors palette, and a lot more than other raster image formats which are a static array of pre-computed pixel values.
3/9

For a long time, SVG did not get the adoption we were hoping for because it was not supported in Internet Explorer. Internet Explorers support of SVG (and with great performance), has been a pivotal moment for the adoption of this standard. It meant that SVG would from now on be an image format supported across all modern browsers.
What is the future of SVG in terms of interactivity? Data visualization?

I think that there are two axes for moving SVG forward. One axis is the addition of features; for example, support for varying stroke width or new ways of specifying path data. I think these are interesting, but less important than the second axis. That second axis is the better integration of SVG with HTML. In particular, the integration of core graphical capabilities (such as filling, stroking, transforming, masking, clipping) would be easier to use across the board by developers if they were consistent. Work on this second axis is in large part happening in the FX Task Force in W3C where the CSS and SVG working group collaborate. A great example of that work is the collaboration to make CSS and SVG Transforms consistent which has resulted in a new combined specification (http://www.w3.org/TR/css3-transforms/).

SVG POLAR CLOCK - GENERATE WITH RAPHAEL.JS

4/9

You also work on the W3C CSS-SVG FX Task Force. What is the purpose of this group? What important innovations are coming from the work here?

CSS can be used to style SVG and HTML. The CSS group, historically, was formed to provide a styling solution for HTML. The FX task force is making sure that SVG and HTML styling work in a consistent way for things that apply to both. With this task force, we are closer to unifying styling for SVG and HTML. For example, the group is finishing work to make CSS Transforms applicable to SVG and HTML elements consistently (syntax, properties, etc.). The same task force is responsible for bringing Filter Effects (https://dvcs.w3.org/hg/FXTF/ raw-file/tip/filters/index.html) to the Web which allows the application of blur, grayscale and other rendering functions on content of selectors. These effects, while originating from the SVG effort, will apply to both HTML and SVG elements consistently and it is exciting to see support appearing already in browsers.
Youve helped define innovative modules for CSS3 such as Shaders, Regions and Exclusions. What possibilities do these new modules allow for web designers and developers that did not exist before?

The Web has come a long way in being able to capture the creative intent of designers. But there were still some areas that were missing. In particular, we think there is a very big need around responsive, magazinelike layouts features for the Web. There are many things designers do for print media that are not yet available on the Web, like interleaving multiple threads of content and directing them to carefully designed templates or defining arbitrarily shaped exclusions areas around which text and other content flows. This is why we are proposing features such as CSS Regions (http:// www.w3.org/TR/css3-regions/) and CSS Exclusions and Shapes (http://www. w3.org/TR/css3-exclusions/). We are working with the CSS working group on these specifications and addressing the requests and comments that are being made with our co-editors (Microsoft in the case of these specifications). While addressing the comments, we have made additional proposals, such as CSS Pagination Templates (http://dev. w3.org/csswg/css3-page-template/) and CSS Pseudo-Elements (http://
5/9

adobe.github.com/css-pseudo-elements/docs/css4-pseudoelements.html) which all go in the direction of increasing expressivity for the advanced layout use cases. Another area which we focus on is cinematic effects. We feel that efforts such as CSS Filter Effects (https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html) and CSS Transforms are really key to enable a new generation of user experience on the Web. While they can be used to create visually stunning experiences, we feel they will be the cornerstone for subtle, but experience-enhancing, effects that will guide the end-users through interactions. I think this is very exciting and we are very happy that after all of our work, the CSS custom filters proposal (originally called CSS Shaders: http://www.adobe.com/devnet/html5/articles/cssshaders.html) we made in October 2011 is now part of the CSS Filter Effects specification. CSS shaders allow animated and interactive 3D effects applied to any Web content and will, I believe, unleash a set of effects we are only beginning to imagine. Finally, there are some basic graphical effects that are sometimes missing from the Web stack. For example, masking and compositing is not yet available accross HTML and SVG. The CSS Masking and Compositing proposal aims at addressing that need.

Thanks to the effort on the canvas, CSS3, and the rising importance of SVG, we now have more advocates for standards around Web graphics.

6/9

How can the web be made more visual with web standards? What is the direction of web standards in this area?

I think there was little attention in this area before 2008, because browsers were focused on getting good CSS interoperability, a good base to build upon and graphical features were not the priority. Thanks to the effort on the canvas 2D and 3D contexts, CSS3, and the rising importance of SVG, we now have more and more advocates for standards around Web graphics. Adobe is extremely interested in contributing in this area and help advance visual effects on the Web through Open Web standards. These things are in our companys DNA. Currently, as I mentioned earlier, we are working on making Regions, Custom Filters and Exclusions advance to the next stage of the standards process along with implementing these features in WebKit. Thanks to other browser vendors & creative developer-designer hybrids, we have renewed interest in this area. So, stay tuned for more standards that will provide even more powerful features!
Can you provide some detail on projects you are working on?

Sure! We work with a lot of people and groups who are helping advance the web. We work with the CSS Working Group and the SVG working group on the proposals and specification drafts related to advanced layout, graphical features and cinematic effects. We are working to resolve the pending issues raised with the specification, so we can have more browsers implement them. For example, we have written up a proposal to make the masking features currently available on WebKit be a standard ( http://dvcs.w3.org/hg/FXTF/raw-file/tip/ masking/index.html ). We are also contributing implementations of the features we propose to WebKit. For example, we have almost completed the implementation of custom filters. We are also in the process of implementing Exclusions in WebKit (see a series of entertaining blog posts on this topic: http://hansmuller-webkit. blogspot.com/ ). We are also in the process of providing an interface within WebKit Developer Tools to analyse CSS Regions in addition to contributing code to complete the implementation of CSS Regions within WebKit. Another project we work on in our team is the Chromium Embedded Framework (CEF) which is a wrapper on top of Chromium so that it can be used as a rendering and design
7/9

surface by an application. For example, the Brackets code editor (http://brackets.io - a tool built with Web standards to edit Web formats) uses the Chromium Embedded Framework. It is an open source project so others can use it. For example, the AppJS (a powerful shell for creating desktop Web applications) uses CEF. One project that I am particularly excited about is the Cordova project ( http://incubator. apache.org/cordova/ ), happening at Apache. This project comes from Nitobi and its popular PhoneGap software. Nitobi is a company Adobe acquired last year. Cordova enables developers to use their JavaScript, CSS and HTML development skills to create mobile applications. We are working with partners on this project (for example Microsoft and Google) and I am really happy that it lowers the barriers for more people to be able to create applications and deploy them to multiple platforms (at a minimum iOS and Android) without having to write native code and wrestling with the quirks of each platforms programming language or APIs.
What is your vision for the web?

I think a Web where graphical features are consistent, whether they apply to boxes (for HTML elements) or shapes (for SVG), is important and I think this will happen over time. I also think a more sophisticated layout model is needed, and beyond the current efforts around flow layout and exclusions. For example, having design grids and the ability to align lines from different blocks is important. I also think this will happen as there are already early stage discussions about these features. To summarize, I think we are moving towards a more graphical, more expressive Web which will be better able to capture the content authors design intent. I believe the coming graphical and feature richness of the Web platform will enable online experiences that we have not yet seen. For example, as I mentioned earlier, features like CSS custom filters (formerly known as CSS shaders) will be used not only for Hollywood-style awe-inspiring effects, but also in subtle user-experience enhancing ways. I also think the Web technologies will be used and be highly successful beyond the browser, most notably in applications (in particular on Mobile, with technologies such as Cordova/ PhoneGap) and in digital publishing for content such as this magazine.

8/9

questions
by

3 SCANDALOUS
duane the anchorman

Which weather is the best: Lannion (Brittany, France) or California ? I love Lannion, my home town and the place where my parents and brother live. I visit whenever possible and we spend vacations in that area. The way we think about the iffy weather is that good weather comes several times a day. This said, I think we are pretty much northern Californians by now and we have been Palo Alto settlers for several years, the longest we have lived in any place! And yes, the beautiful weather contributes to us loving that city, in addition to the fantastic technology area it is and friends we have there. Is it possible to find decent crepes in San Francisco? Actually, I do not know, I am ashamed to say, because we make them at home: my wife does the Crepes de froment and I make the savory kind. But I can tell you that if you ever go to Perros-Guirec in Brittany (http://www.perros-guirec.fr), you should not forget to visit Les Bles Noirs: they make the best Galettes (savory crepes) that I know. And they even serve Lait Ribot (a kind of yogurty drink) which was one of the two traditional drinks people used to have with Galettes (the other one is cider). How is Laurel doing? Very funny! I have not been asked this since middle school, this is rejuvenating :-)

appliness
RIVETS.JS

LIBRARY OF THE MONTH

WE LIKE TO HIGHLIGHT COOL MICRO-FRAMEWORKS IN APPLINESS. THIS MONTH WE WANt TO SHOWCASE Rivets.js, a declarative data binding facility that plays well with existing frameworks such as Backbone.js, Spine.js and Stapes.js.

UI IN PLAIN HTML
Describe your UI in plain HTML using data attributes: //SIMPLE UI <div id=auction> <h1 data-text=auction.title></h1> <img data-src=auction.image_url> <span data-text=auction.timeRemaining | time></span> <div class=alert-box data-show=auction.endingSoon> <p>Hurry up! This auction is ending soon.</p> </div> <dl> <dt>Highest Bid:</dt> <dd data-text=auction.bid | currency></dd> <dt>Bidder:</dt> <dd data-text=auction.bidder></dd> </dl> <dl> <dt>Bids Left:</dt> <dd data-text=user.bidCount></dd> </dl> </div>

Then tell Rivets.js what model(s) to bind to it: rivets.bind($(#auction), {auction: auction, user: currentUser});

Configure
Use rivets.configure to configure Rivets.js for your app (or you can set configuration options manually on rivets.config). Adapter Rivets.js is model interface-agnostic, meaning it can work with any event-driven model by way of defining an adapter. This is the only required configuration as its what Rivet.js uses to observe and interact with your model objects. An adapter is just an object that responds to subscribe, unsubscribe, read and publish. Here is a sample configuration with an adapter for using Rivets.js with Backbone.js. rivets.configure({ adapter: { subscribe: function(obj, keypath, callback) { callback.wrapped = function(m, v) { callback(v) }; obj.on(change: + keypath, callback.wrapped); }, unsubscribe: function(obj, keypath, callback) { obj.off(change: + keypath, callback.wrapped); }, read: function(obj, keypath) { return obj.get(keypath); }, publish: function(obj, keypath, value) { obj.set(keypath, value); } } }); Prefix and data preloading To prevent data attribute collision, you can set the prefix option to something like rv or bind so that data attributes are prefixed like data-rv-text. rivets.configure({ prefix: rv }); Set the preloadData option to false if you dont want your bindings to be bootstrapped with the current model values on bind. This option is set to true by default. rivets.configure({ preloadData: false });

2/4

Extend
Rivets.js is easily extended by adding your own custom binding routines and formatters. Rivets.js comes bundled with a few commonly used bindings, but users are encouraged to add their own that are specific to the needs of their application. Binding Routines Binding routines are the functions that run when an observed attribute changes. Their sole concern is to describe what happens to the element when a new value comes in. All binding routines are publicly available on the rivets.routines object. Lets say we wanted a data-color binding that sets the elements color, heres what the routine function for that binding might look like: rivets.routines.color = function(el, value) { el.style.color = value; }; With that routine defined, the following binding will update the elements color when model.color changes: <span data-color=model.color>COLOR</span> Available bindings out-of-the-box: data-text, data-html, data-value, data-show, data-hide, data-enabled, data-disabled data-checked, data-unchecked, data-[attribute], data-on-[event], data-each-[item] Formatters Formatters are simple one-way functions that mutate the incoming value of a binding. You can use them to format dates, numbers, currencies, etc. and because they work in a similar fashion to the Unix pipeline, the output of each feeds directly as input to the next one, so you can stack as many of them together as you like. rivets.formatters.money = function(value){ return accounting.formatMoney(value); }; rivets.formatters.date = function(value){ return moment(value).format(MMM DD, YYYY); }; <span data-text=event.startDate | date></span>

Usage
Rivets.View and Rivets.Binding The rivets.bind function returns a bound Rivets.View instance that you should hold on to for later. You may want to unbind its listeners with view.unbind() and/or rebuild its bindings with view. build(). You can also access the individual Rivets.Binding instances inside the view through view. bindings this is useful for debugging purposes or if you want to unbind or manually set the value for certain bindings.

3/4

Adapter Bypass If your model object encapsulates its attributes (e.g., model.attributes for Backbone.js models) and your adapter conforms to that object specifically, you can still utilize properties defined outside of that object such as functions or other static values defined on the object root. Just use model:property instead of model.property inside your binding declaration and Rivets.js will bypass the adapter completely and access that property as its defined on the object root. This obviously wont sync any changes, but that is by design in this case as these properties should be mostly static and used in conjunction with other dynamic properties. Computed Properties Computed properties are functions that get re-evaluated when one or more dependent properties change. Declaring computed properties in Rivets.js is simple, just separate the function from its dependencies with a >. The following data-text binding will get re-evaluated with event.duration() when either the events start or end attribute changes. <span data-text=event:duration > start end></span> Iteration Binding Use the data-each-[item] binding to have Rivets.js automatically loop over items in an array and append bound instances of that element. Within that element you can bind to the iterated item as well as any contexts that are available in the parent view. <ul> <li data-each-todo=list.todos> <input type=checkbox data-checked=todo.done> <span data-text=todo.summary></span> </li> <ul> If the array youre binding to contains non-model objects (they dont conform to your adapter), you can still iterate over them, just make sure to use the adapter bypass syntax in doing so, the iteration binding will still update when the array changes, however the individual items will not since theyd be bypassing the adapter.subscribe. <ul> <li data-each-link=item.links> <a data-href=link:url data-text=link:title></span> </li> </ul> Also note that you may bind to the iterated item directly on the parent element. <ul> <li data-each-tag=item.tags data-text=tag:name></li> </ul> DOWNLOAD RIVETS The project is on GitHub !!!

https://github.com/mikeric/rivets

BU I

LT

W IT

PH

EG

AP

appliness

SHOWCASE

HealthTap

HealthTap is the best way to quickly find trusted, reputable doctor answers to health questions anytime, anywhere for free!

This application has been developed with web standards and PhoneGap. It looks very professional, and the app is available on iPhone and Android smartphones. As a patient, you can get fast, free, trustworthy health answers on any symptom, condition, medication or health concern from over 11,000 of the best U.S.-licensed doctors from the comfort of your mobile device. There are also some live chat features. You can connect with doctors on your mobile device by starting private conversations in a safe, HIPAA-secure environment. Thanks to geolocation, you can find the best doctors near you and schedule a time to see them in person right from the app! Its a fantastic app to showcase how professional hybrid applications can be. Sean Mehra just spoke about this highly successful PhoneGap app at the San Francisco Meetup. You can follow him on Twitter! https://twitter.com/seanmehra

We believe that the whole notion of mobile revolution, smartphones, cloud computing and the social engagement are coming together in extremely powerful ways that were not possible even five years ago when we started the previous company, said Ron Gutman, HealthTaps founder and CEO.

TricycleStudios

scienceandhealthcaremarketing

Technical advancements allow creativity to thrive while creativity helps to simplify the technical aspect.
1/6

Thank you for talking with us, Can you tell us a bit about your company?

Tricycle Studios is a Tampa-based creative agency that has been focused on medical marketing since opening its doors 15 years ago. We work with some of the worlds leading medical device companies to present their life-saving solutions in comprehensible, interesting, and memorable ways. We believe that the work we do helps save lives - every day.
You have a very cool office in an historic part of town where a lot of creative types like to congregate. How important has this location been to success of your company? What else about your office and/or location makes Tricycle unique?

Before moving to the historic Ybor City area of Tampa in 2011, we worked from a restored 1920s twostory bungalow in South Tampa. We believe that environment plays a very important role in the creative process by helping spark great collaboration. A great building and a great location help attract other like-minded creative people which, of course, is the core of any creative agency. Our new building is a turn of the century brick classic that would have been Floridas oldest restaurant if the original owners had not moved across the street. Ybor City is the historic cigar manufacturing district of Tampa and has a vibe all its own. Ybor City is increasingly a hub of creative agencies. If you have a chance to visit Tampa, make sure to stroll through this great little enclave.
Can you tell us about the products and services your company provides?

As a creative agency focused in the medical space, we are interested in a


LEFT to RIGHT: Randy Rosenthal (Creative Director and Marketing Genius), Tona Bell (President and Crafting Maven), Chris Lane-Lightfoot (Studio Director and Helicopter Pilot) and Neil Beardsley (Technology Director and Digital WizKid - NOT PICTURED).

2/6

lot of the same issues that our clients are focused on: important developments in treating disease states, mechanisms of action for products that are being developed, and how to best explain these to physicians and patients. Many of us at Tricycle have medical backgrounds and are here because we have a passion for medicine and believe that this is how we can make the world a better place. We focus first on the story to be told and then choose the best art and technology to communicate the message. Our main service is providing fresh ideas to solve our clients challenges in fun and surprising ways. Our core competencies are videography, 2D and 3D animation, impactful storytelling, and immersive environments for tradeshows and education. Of course, digital genius is the underlying engine that makes everything work. We have created everything from interactive digital walls allowing people from different countries to dance together, to mobile selling platforms that allow sales reps to carry the most up-to-date information about the products they sell. Currently we are focusing on mobile informational delivery platforms. We have developed the systems and infrastructure to deliver customized information spanning multiple products. This information is then segmented to address the interests and needs of the individual consumer. If a cardiac surgeon is interested in new tools to address bleeding challenges, our platform will present the solutions that are appropriate for cardiac surgery, as well as videos of use cases, relevant support material, interviews with other cardiac specialists, and more. This segmentation allows a much more focused conversation to take place.

3/6

What needs do your products satisfy in the medical community that did not exist before?

It has always been challenging to keep up with the pace of medicine. As disease states are better understood and new products are developed, timeframes have become more compressed. Digital media and web-based delivery systems are extremely helpful in keeping information relevant, but a big challenge for medical sales reps is that they cannot guarantee internet connectivity in a hospital environment. Mobile devices like the iPad have changed the game by allowing a rep to load huge volumes of information on a small device. Now, a medical sales rep can share important information with a surgeon at a scrub sink and then immediately email a copy of the material to the surgeons assistant. Other information delivery systems tend to focus solely on delivering files. They provide a menuing system that allows the user to get to a particular file, such as a PDF or video, that is developed with neither the device nor digital delivery in mind. As a result, the rep is using a print-formatted document and trying to scroll and swipe around the screen to get to the pertinent information. We do things differently. We start by evaluating the sales conversation. Then we dissect and reassemble the existing sales aids to support the conversations. We build unique media assets to support the conversation, but in a non-linear way, since most conversations do not follow a linear path (no matter how much we may want them to). The end result is a highly usable information delivery system that supports conversational and consultative selling. All of the legacy information (the files we discussed earlier) is still available in an emailable library that allows the physician to research information further through links to the files on the clients website. This provides an opportunity to continue the sales conversation.
What HTML5 technologies do you leverage in your product platform?

With the adoption of mobile platforms, HTML5 has become the common thread that allows us to develop once and deploy on multiple devices. We are always on the lookout for great solutions that we can leverage but we are careful to avoid technologies that are weighted down with features that we do not need. We also have had good results using HTML5 technologies such as offline storage, 3D rendering, Web Workers, Audio and Video.
4/6

What was your decision path to deciding on using HTML5? Have you considered other technologies?

Like many companies we spent the Flash Years happily allowing Flash to help us develop once, deploy many. When that option did not make it to the iPad, we moved to HTML5. HTML5 is still the Wild West of development, without a lot of the tools that other languages take for granted. Because we can focus on a single platform (iPad), a lot of the existing frameworks did not make sense since they provide a lot of crossplatform functionality that we did not need. We developed our own framework to stay lean and allow the fastest user experience. We use HTML5/ CSS/Javascript with JSON data files. On the back end we use content distribution network (CDN) servers with SQL databases and primarily Python scripting. Very little of what we use is off-the-shelf.
Do you use a methodology when developing your applications?

Like a lot of development teams we use pieces of Agile methodology. Being a creative agency at the core we have a lot of processes in place that are focused on creative execution and quality. We dovetail the agency methodologies with software development methodologies to make a hybrid that works for us... and in everything we do, we embrace evolution.
Do you use any frameworks? If so, which ones and what benefits have they provided in the development process?

Weve had great success with Highcharts (http://www.highcharts.com), Tornado, MongoDB.


The world of web development is rapidly changing, how does your team keep up with this evolution?

Our team is constantly working on new projects and contributing to the thriving OSS community. We also have Feature Fridays where the App Team comes together to flex their muscles and think about and implement new features using new technologies or methodologies.
How important have web technologies been in the success of your company?
5/6

Web technology advancement has allowed us to become much more flexible with the

things we can offer and the ease with which we can implement them. There are so many web technologies that allow us to collaborate with our clients and with other creative teams (GitHub, Box.com, Google docs, MindMeister, Basecamp, Mechanical Turk to name a few).
What technical skills are most important when hiring developers?

The skills that we look for are less technical and more about goals and work ethic. We look for talented people with the basic skills (HTML, CSS, Javascript, JSON), one or more advanced skills (Python, iOS, etc) and a passion to learn, attention to detail, and a proven history of a desire to work hard. Above all is the ability to be proactive... as defined in Wikipedia proactive behavior involves acting in advance of a future situation, rather than just reacting. It means taking control and making things happen rather than just adjusting to a situation or waiting for something to happen. Proactive employees generally do not need to be asked to act, nor do they require detailed instructions.
The products you develop are quite technical for clients who are also quite technical, yet you have a team that is very creative as well. How important is it to Tricycle to have a balance of the two characteristics?

Creativity and technicality are not diametrically opposed thought processes. Technical advancements allow creativity to thrive while creativity helps to simplify the technical aspect. The two go hand-in-hand and are extremely important to balance.
What steps do you take to ensure that creativity is still prominent in the products and services you deliver?

We work very hard to maintain a creative spirit and a fun and upbeat workplace. It requires effort to create a workplace that honors creativity and we find that fun and upbeat are the factors that allow creativity to flow.
What is the significance of the Tricycle?

Our creative director came up with the name from watching his young daughters approach to solving problems. Children find creative solutions by mixing exploration, contemplation and a good dose of PLAY. The name Tricycle helps keep us centered in those three pillars.
What well wishes or parting thoughts would you like to leave our readers?

6/6

Follow your passion! Who would have thought that a group of creative individuals with a passion for the science of medicine could grow a creative agency where both passions could be honored.

appliness

BLEEDING EDGE

MAGAZINE-LIKE LAYOUT FOR THE WEB WITH CSS REGIONS AND EXCLUSIONS

caution: This article discusses APIs that are not yet fully standardized and still in flux. Be cautious when using experimental APIs in your own projects.

INTRODUCTION
The web is an extremely powerful platform for text, an area where Adobe has a great deal of experience and expertise. Therefore, when Adobe was looking for ways to help move the web forward, advancing the webs text capabilities even further seemed like an obvious place for us to start. The web generally assumes a single column, vertical orientation for text. Although its possible to flow text around graphics, and even to format text into multiple columns with CSS, its still very difficult to achieve true magazine-like layout on the web. With CSS Regions and CSS Exclusions, Adobe is spearheading the effort to bring the power of desktop publishing to modern browsers. For instance, in the screenshot to the right, CSS Exclusions is being used to flow text along the contour of the mountain:

The document in the screenshot to the right also uses CSS Exclusions to allow the text to wrap around shapes in the images, as well as CSS Regions to format text into columns and around a pull quote:

css regions
Before getting into the details of CSS Regions, Id like to cover how regions can be enabled in Google Chrome. Once you have CSS Regions enabled, you can try out some of the samples referenced in this article, and create your own. ENABLING CSS REGIONS As of version 20 of Chrome (version 20.0.1132.57, to be exact), CSS Regions is enabled through the chrome://flags interface. To enable CSS Regions, follow these steps: 1. Open a new tab or window in Chrome and type chrome://flags in the location bar. 2. Use find in page (control/command + f) to find the CSS Regions section. 3. Click on the Enable link. 4. Click on the Relaunch Now button at the bottom. For more information on Chromes flags, see my blog post on All About Chrome Flags. Once youve relaunched your browser, youre free to start experimenting with CSS Regions. AN OVERVIEW OF CSS REGIONS CSS Regions allows a block of semantically marked-up text to automatically flow into boxes (currently elements). The diagram to the right demonstrates the separation of text (the flow) and boxes (the regions the text flows into):

2/11

Lets take a look at an actual CSS Regions use case. In addition to being a developer at Adobe, Im also a science fiction writer. I frequently publish my work online under a Creative Commons license, and in order to allow it to work across the maximum number of devices and browsers, I frequently use an extremely simple format similar to this:

Using CSS Regions, I was able to create an experience that is both more visually interesting, and much more functional since its easier to navigate and more comfortable to read:

3/11

For demonstration purposes, I added the ability to reveal CSS Regions in this prototype. The screenshot below shows how the regions are arranged such that they give the impression of being columns that wrap around a graphic and a pull-quote in the center:

You can experiment with this prototype (as well as view the source code) when you are at your computer by going to this site: http://christiancantrell.com/adobe/hlp/callout.html. CREATING A NAMED FLOW The CSS required to get a block of text to flow through regions is extremely simple. The snippet below assigns a named flow called article to a div with the id content, and assigns that same article named flow to any element with the class region. The result is that text contained inside the content element will automatically flow through any element with the class region. <!DOCTYPE html> <html> <head> <style> #content { +flow-into: article; } .region { +flow-from: article; box-sizing: border-box; position: absolute; width: 200px; height: 200px; padding: 10px; } #box-a { border: 1px solid red; top: 10px; left: 10px; }
4/11

#box-b { border: 1px solid green;

top: 210px; left: 210px;

#box-c { border: 1px solid blue; top: 410px; left: 410px; } </style> </head> <body> <div id=box-a class=region></div> <div id=box-b class=region></div> <div id=box-c class=region></div> <div id=content> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent eleif end dapibus felis, a consectetur nisl aliquam at. Aliquam quam augue, moles tie a scelerisque nec, accumsan non metus. Lorem ipsum dolor sit amet, con sectetur adipiscing elit. Proin cursus euismod nisi, a egestas sem rhoncus eget. Mauris non tortor arcu. Pellentesque in odio at leo volutpat conse quat.... </div> </body> </html> The result looks like this:

5/11

Note that the text inside the content div doesnt have any knowledge of its presentation. In other words, it can remain entirely semantically intact even as its flowing through various regions. Additionally, since regions are just elements, they are positioned and sized using CSS just as any other element, and are therefore perfectly compatible with responsive design principles. Designating elements as part of a named flow simply means that the specified text automatically flows through them. THE CSS OBJECT MODEL To be concise, this section uses only one vendor prefix (webkit), but you should write code that works across browsers that support this feature! The CSS Object Model, or CSSOM, defines JavaScript APIs for working with CSS. Below is a list of the new APIs related to CSS Regions: document.webkitGetFlowByName(flow_name): The webkitGetFlowByName function returns a reference to a named flow. The argument corresponds to the name specified as the value of the flowinto and from-from CSS properties. To get a reference to the named flow specified in the code snippet above, you would pass in the string article. WebKitNamedFlow: The webkitGetFlowByName function returns an instance of WebKitNamedFlow with the following properties and functions: contentNodes: A reference to the nodes that flow into the named flow. overflow: Whether or not the content is overflowing the specified region. In other words, whether or not more regions are required to contain all the content. getRegionsByContentNode(node): A function that returns a reference to the region containing the specified node. This is especially useful for finding regions containing things like named anchors. webkitRegionLayoutUpdate event. Elements that are part of flows can register for webkitRegionLayoutUpdate events. Event handlers are invoked whenever the flow changes for any reason (content is added or removed, the font size changes, the shape of the region changes, etc.). Element.webkitRegionOverflow: Elements have a webkitRegionOverflow property which, if they are part of a named flow, indicates whether or not content from a flow is overflowing the region. Possible values are fit if the content stops before the end of the region, and overflow if there is more content than the region can hold. One of the primary uses for the CSSOM is listening for webkitRegionLayoutUpdate events and dynamically adding or removing regions in order to accommodate varying amounts of text. For instance, if the amount of text to be formatted is unpredictable (perhaps user-generated), if the browser window is resized, or if the font size changes, it might be necessary to add or remove regions to accommodate the change in the flow. Additionally, if you want to organize your content into pages, you will need a mechanism for dynamically modifying the DOM as well as your regions. The following snippet of JavaScript code demonstrates the use of the CSSOM to dynamically add regions as necessary. Note that for the sake of simplicity, it does not handle removing regions or defining the size and positions of regions; it is for demonstration purposes only. function addRegion() { var region = document.createElement(div); region.classList.add(region); region.addEventListener(webkitRegionLayoutUpdate, onLayoutUpdate); document.body.appendChild(region); } function onLayoutUpdate(event) { var region = event.target; if (region.webkitRegionOverflow === overflow) { addRegion();

6/11

} else { regionLayoutComplete(); }

function regionLayoutComplete() { // Finish up your layout. } Several more CSS Regions demos are available here. CSS PAGE TEMPLATES This section discusses future concepts not yet implemented in any browser. Leveraging the CSSOM is probably the most powerful and flexible way of implementing things like paging and responsive layout, but Adobe has been working with text and desktop publishing tools long enough to know that designers and developers are also going to want an easier way to get relatively generic paging capabilities. Therefore we are working on a proposal called CSS Page Templates which allows paging behavior to be defined entirely declaratively. Lets take a look at a common use case for CSS Page Templates. The code snippet below shows the use of CSS to create two named flows: article-flow and timeline-flow. Additionally it defines a third selector called combined-articles inside of which the the two flows will be contained. The simple inclusion of the overflow-style property inside the combined-articles selector indicates that the content should automatically be paged along the x axis, or horizontally: <style> #article { +flow-into: article-flow; } #timeline { +flow-into: timeline-flow; } #combined-articles { overflow-style: paged-x; } </style> Now that the flows have been defined and the desired overflow behavior has been specified, we can create the page template itself: @template { @slot left { width: 35%; float: left; +flow-from: article-flow; } @slot time { width: 25%; float: left; +flow-from: timeline-flow; }

7/11

@slot right { width: 35%; float: left; +flow-from: article-flow; }

Page templates are defined using the new at syntax. In the code snippet above, we define three slots, each corresponding to a column. The text from the article-flow will flow through the columns on the left and right, and text from the timeline-flow will populate the column in the middle. The result might look something like this:

Note that the article text -- the text in the left- and right-hand columns -- is English, and the timeline in the center is German. Additionally, the document pages horizontally without the need for any JavaScript code. Everything was done entirely declaratively in CSS. CSS Page Templates are still a proposal, however we have a prototype which uses a JavaScript shim (a.k.a polyfill) in order to allow you to experiment with them now. To learn more about CSS Regions in general, check out the CSS Regions page on html.adobe.com.

8/11

CSS EXCLUSIONS
In order to achieve true magazine-like layout, its not enough to be able to flow text through regions. A critical element of high-quality and visually interesting desktop publishing is the ability to make text flow either around or inside of irregular graphics and shapes. CSS Exclusions is bringing this level of production quality to the web. The screenshot below is from a CSS Exclusions prototype, and shows text dynamically flowing around a path that matches the contour of a large rock formation:

The inverse is illustrated in the next screenshot: text flowing inside of irregularly shaped polygons:

9/11

The first step to being able to flow text around or inside of arbitrary shapes is to develop and optimize the required algorithms. Adobe is currently working on implementations which will be contributed directly to WebKit. Once these algorithms have been optimized, they will become the foundations on top of which the remainder of CSS Exclusions are built.

For more information on CSS Exclusions, see the CSS Exclusions page on html.adobe.com, and for a more detailed look at Adobes work on the underlying technology for CSS Exclusions, see Hans Mullers blog post entitled Horizontal Box: Polygon Intersection for CSS Exclusions. THE CURRENT STATE OF CSS REGIONS AND CSS EXCLUSIONS The first time I talked about CSS Regions and CSS Exclusions publicly was at the Adobe Developer Pod at Google I/O 2011. At the time, I was showing demos in our own custom prototype browser. The reception was extremely enthusiastic, however there was a palpable sense of disappointment when onlookers discovered that none of the functionality I was showing was available in any of the major browsers yet. I was at Google I/O again this year (2012), this time as a presenter along with my coworker Vincent Hardy and Alex Danilo from Google (you can watch the presentation here). Just one year later, about 80% of the CSS Regions specification has been implemented in WebKit, and is already in the most recent version of Google Chrome (note that CSS Regions currently has to be enabled through chrome://flags). Preliminary support for CSS Regions has even landed in Chrome for Android:

Additionally, both CSS Regions and CSS Exclusions are implemented in the Internet Explorer 10 preview, and are currently on Mozillas 2012 roadmap for Firefox. The next major version of Safari should support the majority of the CSS Regions specification, and subsequent updates should include the remainder.

10/11

Below is a detailed timeline of the progress weve made with CSS Regions and CSS Exclusions since our initial proposal to the W3C in April of 2011:

CONCLUSION
Adobe has a huge amount of experience with text, fonts, and with desktop publishing in general through tools like InDesign. Although the web is already a very powerful platform for text, we want to use our knowledge and experience to push text presentation even further. CSS Regions and CSS Exclusions are allowing content to remain semantically structured while also enabling true magazine-like layout, and ultimately a much more expressive web.

ABOUT THIS ARTICLE


Christian Cantrell is a science fiction writer and software developer living in Northern Virginia. He currently works for Adobe Systems as a Technical Product Manager on the Web Platform team. His novel Containment has sold well over 100,000 copies.

ONLINE RESOURCES CSS Object Model (CSSOM) http://dev.w3.org/csswg/cssom/


CSS Regions http://dev.w3.org/csswg/css3-regions/ CSS Exclusions http://dev.w3.org/csswg/css3-exclusions/

http://www.livingdigitally.net/

@cantrell

appliness

HELTER SKELTER NEWS

Fresh news about HTML and Javascript collected by Brian Rinaldi - remotesynthesis.com

DOM: element IDs are global variables via Axel Rauschmayer

JavaScript Events And Responding To The User via Christian Heilmann Dont Overthink It Grids via Chris Coyier

Understanding the CSS3 Flexbox (Flexible Box Layout Module) via Ben Frain

CSS Tooltips via David Walsh

A closer look at _.extend and copying properties via Dr. Axel Rauschmayer

Using Underscore.js Templates To Render HTML Partials via Ben Nadel

Node.js for Beginners by Maciej Sopyo

Backbone.js (Sub)View Rendering Trick via Joe Zim

appliness

HELTER SKELTER NEWS

Getting HTML5 Ready ContentEditable via Brian Rinaldi

Geo-Targeted House Ads via Pamela Fox Towards A Retina Web via Reda Lemeden

Proof of Concept Build a download feature for IndexedDB via Ray Camden

How Ender Bundles Libraries for the Browser via Rod Vagg

CreateJS and HTML5 Canvas: resize, fullscreen and liquid layouts via Fabio Biondi

PhoneGap Build adds Hydration via Ray Camden

Creating a Mobile Web Application Part 1: Mobile Design via Johnny Simpson

Adobe Edge Animate Preview by Adobe

MORE NEWS ON remotesynthesis.com

FO LL OW

APPLM

BE CO

INE
JOIN THE APPLINESS COMMUNITY

- FACEBOOK PAGE - ON TWITTER - ON GOOGLE+ - OUR NEWSLETTER

O
- CONTACT US - SHARE AN IDEA - WRITE AN ARTICLE - BASH US

TR

IB S U

TE

Appliness is a digital magazine written by passionate web developers. YOU CAN FOLLOW US ON YOUR FAVORITE SOCIAL NETWORK. YOU CAN SUBSCRIBE TO OUr MONTHLY NEWSLETTER. YOU CAN CONTRIBUTE AND PUBLISH ARTICLES. YOU CAN SHARE YOUR BEST IDEAS. YOU CAN BECOME APPLI.

FAN

SS

O F

US

LL FO W O

appliness

THE TEAM
Contribute and join Appliness

Appliness is a free digital magazine edited by passionate web developers. We are looking for contributors. Contact us and join the adventure. Youll find on our website appliness.com a feedback form. You can also follow us on twitter, facebook and Google+.

M I C H AEL
Michal Chaize is a Developer Evangelist at Adobe where he focuses on Rich Internet Application and Mobile applications. Based in Paris, he works with large accounts that need to understand the benefits of rich user interfaces, leverage the existing back-ends to add a rich presentation layer and measure the impact on the existing IT teams. He believes that intuitive user experiences in the Enterprise are key to successful developments of effective, efficient, engaging, easy to learn and error free applications. Before joining Adobe, Michael founded a software company and taught RIA languages such as Flex and PHP in IT engineering schools. Hes the editor in chief of Appliness.

CHAIZE

RAY M O N D

Meet Raymond Camden. He is a 38 year old married father of three living in beautiful Lafayette, Louisiana. Ray is a developer evangelist for Adobe where his primary technical focus is ColdFusion, jQuery, Flex, AIR and the mobile space. Hes been invited to speak at many conferences over the years, including CFUNITED and Adobe MAX .

CAMDEN

LOUIS C H R I S T I AN
Christian Cantrell is a science fiction writer and software developer living in Northern Virginia. He currently works for Adobe Systems as a Technical Product Manager on the Web Platform team. His novel Containment has sold well over 100,000 copies.

C AN T RELL

Louis Lazaris is a freelance web developer based in Toronto, Canada. He blogs about front-end code on Impressive Webs and is a co-author of HTML5 and CSS3 for the Real World, published by SitePoint.

LAZARIS

M I H A I B R I AN
Brian Rinaldi is as a Content and Community Manager for the Adobe Developer Center team, where he helps drive content strategy for HTML5 and JavaScript developer content. Brian blogs regularly at http://remotesynthesis.comand and is a unreformed twitter addict.

CORLAN
RINALDI
Mihai Corlan has been working for Adobe since 2006. Since 2008, he has been working as a developer evangelist for Adobe. His current role is worldwide web developer evangelist. This means he writes code, he writes articles and he speaks.

AN D RE J AY D M I T RY
B ARAN O V S K I Y
Dmitry is a Sydney-based web developer interested in HTML, CSS, JavaScript, XSLT and SVG. Currently he is working at Adobe as a Senior Computer Scientist. Hes the creator of the JavaScript library Raphael.

Andre Jay Meissner is a passionate diving Enthusiast, Tech Geek and Code Freak, Entrepreneur and BDM/ DevRel Web & Mobile at Adobe. He focuses on Webstandards, responsive and Multiplatform Development as well as Gaming. Jay blogs at http://klick-ass. com, can be found on https://alpha.app.net/klick_ass, or met at a conference in your neighborhood soon.

MEISSNER

AN D RE W M A I LE
Maile is the assistant editor for Appliness magazine and has worked with Adobe both as an employee and consultant for 8 years now. Mailestarted with Adobe on the Technical Marketing team as a technical trainer for the Adobe LiveCycle Enterprise Suite (most recently Adobe Digital Enterprise Platform). She then went on to work with the Adobe Enterprise Evangelist team to support great Flex developer resources such as Tour de Flex and Flex.org. Maile is excited to jump into the world of digital publishing and dig deeper into leading edge HTML and related technologies.

VALENTINE

Andrew Trice is a Technical Evangelist with Adobe Systems. Andrew brings to the table more than a decade of experience designing, implementing, and delivering rich applications for the web, desktop, and mobile devices. He is an experienced architect, team leader, accomplished speaker, and published author, specializing in object oriented principles, mobile development, realtime data systems, GIS, and data visualization.

T R I C E

GREG H O LLY
Holly is a Developer Evangelist at Adobe Systems and has been doing software development since 1996 with experience working for various Fortune 500 companies to startup. Hollys experience is primarily in OO languages, but she thrives on constantly learning new things & is always up for a challenge.

S chi n sk y

Greg is a Developer Evangelist at Adobe Systems focusing on the use of Adobe technologies in enterprise applications. Technologies include HTML, JavaScript and related technologies, Flex, AIR, data services, digital publishing, and anything mobile, tablet and desktop app development related. Prior to joining Adobe, Greg architected and developed many largescale applications at Verizon, Motorola, NASA/Boeing and others.

WILSON

Das könnte Ihnen auch gefallen