You are on page 1of 134

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 4th issue of this magazine.

(
TUTORIALS TOOLING FOCUS ON CSS VIDEO TUTORIAL SHOWCASE TEAM

TABLE OF CONTENTS

HTML Templates with Mustache.js


by Christophe Coenraets

ZEPTO AND TOUCH GESTURES


by Michal Chaize

A closer look at Underscore templates


by Axel Rauschmayer

AngularJS App with an Express + Node.js Backend


by Brian Ford

PROTOTYPAL INHERITANCE FOR CLASSICAL DEVELOPERS


by Piotr Walczyszyn

Prototypal Inheritance & Debugging Tough Problems


by Andrew Trice

improving geolocation
by Greg Wilson

BUILD A CHAT WITH NODE.JS AND JQUERY MOBILE


by Michael Chaize

Building PhoneGap applications powered by Database.com


by Andrew Trice

introducing kendo ui mobile


by Holly Schinsky

MEGA LIST JQUERY PLUGIN


by Andrew Trice

Brackets: The Open Source Code Editor for the Web


by Adam Lehman

BRACKETS: Learning from the source


by David Deraedt

INTERVIEW OF ERIC MEYER


by Maile Valentine

CSS FILTERS
by David Walsh

understanding Css filter effects


by Alex Danilo

WebKit, and Filters, and Shaders! Oh, my!


by Alan Greenblatt

CSS OBJECT MODEL


by Divya Manian

INTRO TO BACKSTACK
by Piotr Walczyszyn

WHAT THE PHOTO?


by Rumpus

HELTER SKELTER NEWS

NEWS about html and javascript


by Brian Rinaldi

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

HTML templates address this issue by decoupling the UI definition (HTML markup) from the data. There are a number of HTML template solutions out there: jQuery Templates, Underscore.js, and Mustache.js to name a few. Mustache.js is a popular choice because of its powerful syntax and fast rendering.

HTML Templates with Mustache.js

WHY MUSTACHE.JS
When developing modern HTML applications, you often write a lot of HTML fragments programmatically. You concatenate HTML tags and dynamic data, and insert the resulting UI markup into the DOM. Here is a random code example of this approach: $.each(messages.reverse(), function(index, message) { $(#messageList).append( <li><span class=list-title> + message.userName + </span> + <abbr class=list-timestamp title= + message.datePosted + ></abbr> + <p class=list-text> + message.messageText + </p></li>); } }); The proliferation of this kind of code throughout your application comes with some downsides. The tight coupling of UI and data logic doesnt pro-

ou Playgr

nd

Difficulty
- rookie - intermediate - expert

- HTML t - JavaScrip - RequireJS

Todo list

- hack - write plugin - inspect

by Christophe Coenraets

mote separation of concerns and reuse. It makes your application harder to write and harder to maintain. HTML templates address this issue by decoupling the UI definition (HTML markup) from the data. There are a number of HTML template solutions out there: jQuery Templates, Underscore.js, and Mustache.js to name a few. Mustache.js is a popular choice because of its powerful syntax and fast rendering. Mustache is a logic-less template syntax. Logic-less means that it doesnt rely on procedural statements (if, else, for, etc.): Mustache templates are entirely defined with tags. Mustache is implemented in different languages: Ruby, JavaScript, Python, PHP, Perl, Objective-C, Java, .NET, Android, C++, Go, Lua, Scala, etc. Mustache.js is the JavaScript implementation. In this article, we take a quick tour of some of the capabilities of Mustache.js. To start using Mustache.js, simply add a script tag to your html file pointing to mustache.js which is available on github.

#1

basic template

This is a self-explanatory example. Note that: - Instead of being defined in a variable, the data often comes from a service call (see sample 2) - Instead of being defined in a variable, the template is often read from a file (see sample 3) var person = { firstName: Christophe, lastName: Coenraets, blogURL: http://coenraets.org }; var template = <h1>{{firstName}} {{lastName}}</h1>Blog: {{blogURL}}; var html = Mustache.to_html(template, person); $(#sampleArea).html(html); Result:

Christophe Coenraets
Blog: http://coenraets.org

#2

Basic Template using Ajax data

Same as sample 1, except that we get the data from an Ajax service call. $.getJSON(json/data.json, function(data) { var template = <h1>{{firstName}} {{lastName}}</h1>Blog: {{blogURL}}; var html = Mustache.to_html(template, data); $(#sampleArea).html(html); });
2/8

Result:

John Smith
Blog: http://johnsmith.com

#3

EXTERNALIZED TEMPLATE

Same as sample 2, except that we read the template from the main HTML file. $.getJSON(json/data2.json, function(data) { var template = $(#personTpl).html(); var html = Mustache.to_html(template, data); $(#sampleArea).html(html); }); The template is defined as follows in index.html: <script id=personTpl type=text/template> <h1>{{firstName}} {{lastName}}</h1> <p>Blog URL: <a href={{blogURL}}>{{blogURL}}</a></p> </script> Result:

Lisa Jones
Blog: http://lisajones.com Note: Sample 3 represents the way templates are being used in many dynamic Web applications: - You get data from an Ajax service - You read the template from an external file In the remaining of this article, we declare the data and the template in variables to keep the examples self-contained. Remember to refer to sample 3 for a traditional setup when using templates in a dynamic Web application.

#4

Enumerable Section

3/8

var data = {name: John Smith, skills: [JavaScript, PHP, Java]}; var tpl = {{name}} skills:<ul>{{#skills}}<li>{{.}}</li>{{/skills}}</ul>; var html = Mustache.to_html(tpl, data); $(#sampleArea).html(html);

Result: John Smith skills: JavaScript PHP Java

#5

Enumerable Section with Objects

var data = { employees: [ { firstName: Christophe, lastName: Coenraets}, { firstName: John, lastName: Smith} ]}; var template = Employees:<ul>{{#employees}} + <li>{{firstName}} {{lastName}}</li> + {{/employees}}</ul>; var html = Mustache.to_html(template, data); $(#sampleArea).html(html); Result: Employees: Christophe Coenraets John Smith

#6

NESTED OBJECTS

You can use the dot notation to access object properties. var person = { firstName: Christophe, lastName: Coenraets, blogURL: http://coenraets.org, manager : { firstName: John, lastName: Smith } }; var template = <h1>{{firstName}} {{lastName}}</h1><p>{{blogURL}}</p> + Manager: {{manager.firstName}} {{manager.lastName}};

4/8

var html = Mustache.to_html(template, person); $(#sampleArea).html(html); Result:

Christophe Coenraets
http://coenraets.org Manager: John Smith

#7

Dereferencing

Same as sample 6, except that we dereference the manager object to make it easier to access its properties (without having to use the dot notation). var person = { firstName: John, lastName: Smith, blogURL: http://johnsmith.com, manager : { firstName: Lisa, lastName: Jones } }; var tpl = <h1>{{firstName}} {{lastName}}</h1><p>{{blogURL}}</p> + {{#manager}}Manager: {{firstName}} {{lastName}}{{/manager}}; var html = Mustache.to_html(tpl, person); $(#sampleArea).html(html); Result:

John Smith
http://johnsmith.com Manager: Lisa Jones

#8

Function

Templates can reference functions like totalPrice in this example. var product = { name: FooBar, price: 100,

5/8

}; var template = <p>Product Name: {{name}}</p>Price: {{totalPrice}}; var html = Mustache.to_html(template, product); $(#sampleArea).html(html); Result: Product Name: FooBar Price: 105

salesTax: 0.05, totalPrice: function() { return this.price + this.price * this.salesTax; }

#9

Condition

Templates can include conditional sections. Conditional sections only render if the condition evaluates to true. A conditional section begins with {{#condition}} and ends with {{/condition}}. condition can be a boolean value or a function returning a boolean. var data = { employees: [ { firstName: Christophe, lastName: Coenraets, fullTime: true, phone: 617-123-4567 }, { firstName: John, lastName: Smith, fullTime: false, phone: 617-987-6543 }, { firstName: Lisa, lastName: Jones, fullTime: true, phone: 617-111-2323 }, ]}; var tpl = Employees:<ul>{{#employees}}<li>{{firstName}} {{lastName}} + {{#fullTime}} {{phone}}{{/fullTime}}</li>{{/employees}}</ul>; var html = Mustache.to_html(tpl, data); $(#sampleArea).html(html); Result: Employees: Christophe Coenraets 617-123-4567 John Smith
6/8

Lisa Jones 617-111-232

#10

PARTIALS

var data = { firstName: Christophe, lastName: Coenraets, address: 1 Main street, city: Boston, state: MA, zip: 02106 }; var template = <h1>{{firstName}} {{lastName}}</h1>{{>address}}; var partials = {address: <p>{{address}}</p>{{city}}, {{state}} {{zip}}}; var html = Mustache.to_html(template, data, partials); $(#sampleArea).html(html); Result:

Christophe Coenraets
1 Main street Boston, MA 02106

#11

Partials in Enumerable Section

var data = { depts: [ { name: Engineering, employees: [ {firstName: Christophe, lastName: Coenraets}, {firstName: John, lastName: Smith}] }, { name: Sales, employees: [ {firstName: Paula, lastName: Taylor}, {firstName: Lisa, lastName: Jones}] }] }; var tpl = {{#depts}}<h1>{{name}}</h1> + <ul>{{#employees}}{{>employee}}{{/employees}}</ul>{{/depts}}; var partials = {employee: <li>{{firstName}} {{lastName}}</li>}; var html = Mustache.to_html(tpl, data, partials); $(#sampleArea).html(html);
7/8

Result:

Engineering
Christophe Coenraets John Smith

Sales
Paula Taylor Lisa Jones

Mustache.JS

abuse can

DAMAGE your

LIFESTYLE

appliness

DONT WORRY, BE APPLI

ZEPTO AND TOUCH GESTURES

Recently, I wanted to reproduce the behavior of the iOS pictures gallery in a PhoneGap application. I took this opportunity to start playing with Zepto and its touch gestures plugin. In the end, I developed an application that is very responsive and performs like a native app.

What is Zepto?
Zepto is a JavaScript micro-framework that targets modern browsers. A lot of JavaScript libraries, such as JQuery, were created before the rise of smartphones. Because WebKit is a standard in the mobile space, Zepto focuses primarily on this engine. Thomas Fuchs, the author of Zepto.js, explained at the JSConf 2011 event in Portland why he believes in JavaScript frameworks and why proprietary features, such as CSS selectors, are awesome: //select all li elements with both just and testingclassnames document.querySelectorAll(li.just.testing) // how many paragraphs? document.querySelectorAll(p).length // select even paragraphs document.querySelectorAll(p:nth-child(2n+1)) CSS selectors are very useful, but so is JSON manipulation: JSON.stringify({ s: a string, n: 123, d: new Date})

ou Playgr

nd

Difficulty
- rookie - intermediate - expert

- Zepto - Flickable - CSS 3D

Todo list

- wash fingers

- swipe - play cards

by Michal Chaize

JSON.parse({some:json,test:123}) And Array iteration: [1,2,3].forEach(alert); [].slice.apply(nodelist).forEach( function(element){ alert(element.innerHTML); } ); No more loops required. So thats great, but why use Zepto and not Prototype, jQuery, or other frameworks? First, Fuchs notes that some functionalities are not supported or not meaningful on mobile devices. In addition, more code results in longer download and initialization times. Most of the downloaded code isnt even used (for example, the code that is included to support IE6 will never be used on a mobile device). Zepto reduces code size as much as possible to minimize download and initialization time. It provides an easy-to-use API that mimics jQuery, and many developers already know jQuery. Zepto can also be extended with the jQuery plug-in mechanism. It doesnt cover the entire jQuery API, but most of it. The minified version of Zepto.JS is super small; it is just 8K, compared to jQuery at 100K. So Zepto is awesome for hybrid apps (combined with PhoneGap for instance). Another advantage for mobile app developers is that the source code is clear and concise because it just targets WebKit. As a result the community can easily extend the framework, and thats just what Tom Longo did in creating Flickable.JS, a Zepto plugin to enable touch gestures on any HTML element of your app.

What is Flickable?
Flickable extends Zepto to handle complex touch interactions. Each element of your DOM becomes touchable thanks to this plugin, and you can easily slide elements around the page thanks to hardware accelerated CSS transitions. The integration is very lightweight. You just need to define a <DIV> wrapper element that will contain a Flickable wrapper DIV element. The only constraint is that you need to indicate the number of segments by calling the flickable() method; for example: $(#flickable_wrapper).flickable({segments:3} The plugin simply calculates the width of each segment by dividing the flickable_wrapper width by the number of segments specified (which means that you need to use segments that have the same width). And thats it, you can move your flickable_wrapper around with your finger and the plugin will automatically snap the nearest segment once you lift your finger. It will imitate the classic behavior of a smartphone picture gallery. You can play with the complete list of complex touch events: onStart, onMove, onScroll, onScrollPrev (when an element snaps to the previous segment), onScrollNext, onFlick (a quick swipe with your finger), onFlickLeft, onFlickRight, onFlickUp, onFlickDown, and onEnd. Most events include the event data object which is structured like so: eventData = { // Starting touchpoint [x pos, y pos, timestamp] start: {x:0, y:0, time: 0}, delta: { // Previous touchpoint
2/9

prevPos: {x:0, y:0}, // Distance relative to original touchpoint dist: {x:0, y:0}, // Direction of touch // [-1 left/up, +1 right/down, 0 no movement] dir: {x:0, y:0} }, end: { // Duration of touch duration: 0, // Speed of movement along x and y axis speed: {x:0, y:0}, // +1/-1 if the touch was deemed to // be a flick left/right up/down flick: {x:0, y:0}

} }

Building the iOS menu


Just for fun, I wanted to try to reproduce the iOS menu, specifically the one that displays icons at the bottom of the screen when you double tap the hardware button. To navigate through the menu, you have to swipe left and swipe right. Its a perfect example to show the performance of Flickable. Here is my interactive sample:

He Pla y ! T y w his ith is in thi ter s s ac am tiv ple e ! !

3/9

As you can see, its super responsive and the framework distinguishes between a tap and a swipe event without any problem. The structure of the HTML page is very straightforward. As I mentioned above, you have to declare a wrapper (the visible area), which is #menuWrapper in this case, and the Flickable DIV, which is #menu. Ive implemented just two segments, and each segment displays three icons. <body class=bodyMain> <div id=menuWrapper> <div id=menu> <div class=icons id=icons1> <img src=menuiOS/icon1.png name=dictionnary class=imgIcon/> <img src=menuiOS/icon2.png name=facebook class=imgIcon/> <img src=menuiOS/icon3.png name=maps class=imgIcon/> </div> <div class=icons id=icons2> <img src=menuiOS/icon4.png name=photoshop class=imgIcon/> <img src=menuiOS/icon5.png name=mouse class=imgIcon/> <img src=menuiOS/icon6.png name=settings class=imgIcon/> </div> </div> </div> <div id=help> Swipe left and swipe right to test this iOS-like menu. <br/>Tap an icon to get the name of the app. </div> <div id=app-name> </div> </body> Once the structure is declared, you can import both Zepto and Flickable JavaScript libraries and use Zepto to initialize the Flickable element. As you can see, Zepto uses the jQuery syntax. The tap method must be used on touch screens to catch the tap events on your elements. This code will only work on touch screens! That said, you can use Modernizr to create a fallback mechanism and catch classic click events. But again, I am using Zepto to target smartphones, so in this case I dont care about mouse events. <script src=zepto.min.js></script> <script src=zepto.flickable.min.js></script> <script type=text/javascript> $(document).ready(function() { $(#menu).flickable({segments:2}); $(#menu img).tap(function(){ //alert(You just tapped +$(this).attr(name)+); $(#app-name).text(You just tapped +$(this).attr(name)+); }); }); </script> One call of the flickable() method and it works!!! Magic? Well you also need to declare some properties in the CSS. The wrapper must have a hidden overflow:

4/9

#menuWrapper { width: 464px; height: 130px; overflow: hidden; background: #DDDDDD; background-image:url(menuiOS/iosBackground.png); padding:0; } And the width of the Flickable element (#menu) must be the sum of all the segments: #menu { width: 938px; height: 150px; } Flickable uses CSS 3D transformations that are hardware accelerated; thats why the experience is so smooth. It also uses pure touch events to overcome the 300ms limitation of classic click events and improve responsiveness.

! y z u S t h ig r e r e w You t p i r c S a v a J w e n s i Th is k r o w e m a r f o r mic ! g n i t a n fasci

you s ee !

5/9

Playing cards
To take things one step further, Ive extended an official Flickable sample to create a cool navigation. It could be used to navigate an employee directory. You can swipe to navigate through employees but also tap on a card to flip it and read more information about the employee. Christophe Coenraets (who is the master of the Employee Directory application) should appreciate this sample. Here is the sample. Swipe left, swipe right, and tap on a card to flip it over.

Hey Play ! This with is int this eract sam ive ! ple !

6/9

ADDING (SLOWER) navigation buttons As you can see, I have navigation buttons in the interface. My PREV and NEXT buttons are just images. When the document is ready, you can listen for click events and call the flickable() method with scrollNext or scrollPrev as parameters. $(document).ready(function() { $(.next).click(function() { $(#demo1).flickable(scrollNext);}); $(.prev).click(function() { $(#demo1).flickable(scrollPrev);}); }); <div class=navigationBar> <img src=pics/prev.png width=85 height=44 class=prev/> <img src=pics/next.png width=85 height=44 class=next/> </div>} Ive left click events on intentionally so that you can feel the difference between a tap and a click event. The click event is not as responsive because the browser will wait for 300ms before firing the transition to the next card. This is because the browser wants to make sure that you dont want to double click an element. If you never use double tap events in your interface, you can bypass this limitation. There are numerous articles on the web, including some on the Google developers website, that explain how to enable fast clicks. FLIPPING the cards To enable the card flip, you must use CSS 3D transition and manage two states: .front and .back. Both sides, front and back, are overlaid. To hide the back side, rotate it 180 degrees on the Y axis: .back { color: #fff; -webkit-transform: rotateY(180deg) translate3d(0,0,0); background: url(pics/background3.png); background-size:232px 232px; } Also, specify that if an element is rotated 180, then it should become invisible. This can be done with the webkit-backface-visibility property: .front, .back { background: #fff; position: absolute; top: 0; left: 0; margin: 0; -webkit-backface-visibility: hidden; } Then you can declare a CSS transition: @-webkit-keyframes cardflipped {
7/9

from { -webkit-transform: rotateY(0deg) translate3d(0,0,0); } to { -webkit-transform: rotateY(180deg) translate3d(0,0,0); } } And assign this transition to a CSS style such as flipped: .card.flipped { -webkit-animation-name: cardflipped; } Now you can use Zepto to call the Flickable library (as in the previous sample) and indicate that when the user taps a card, it should assign (or unassign) the flipped style to the front and the back of a card. This can be achieved with the classic toggleClass method introduced with jQuery, and made available in Zepto. $(document).ready(function() { $(#demo1).flickable({segments:3}); $(.front, .back).tap(function() { var el = $(this).parent(); el.toggleClass(flipped) }); }

CleanING UP your HTML code with templates AND Mustache As you can imagine, the HTML code to define a segment (a card) is not as simple as in my previous sample where I just had to display images. In this case, I need to get information about employees, using JSON for instance, and I have to dynamically create the cards. HTML templates are justified in this case, and Ive chosen to use Mustache.js, another micro-framework. If you want to know more about Mustache, read Christophes tutorial on it in this issue. So if you check the final source code of this project, youll find three parts: - the data, which is a JSON object. - the definition of the template, which is a string that combines HTML code and Mustache elements. In the JSON structure, I have authors objects. To loop on authors, I use {{#authors}} {{/authors}}. Then I can use authors properties such as the firstName: <div class=nameDisplay>{{firstName}}</div>. - the Mustache call and initialization. Once the document is ready, you can call Mustache to parse your data, replace all the {{elements}} with text extracted from the data and then use Zepto to inject the string in your DOM: $(document).ready(function() { var html = Mustache.to_html(tpl, json); $(#demo1).html(html); }

8/9

Here is the complete JavaScript code for this example: $(document).ready(function() { var html = Mustache.to_html(tpl, json); $(#demo1).html(html); $(#demo1).flickable({segments:3}); $(.front, .back).tap(function() { var el = $(this).parent(); el.toggleClass(flipped) }); $(.next).click(function() { $(#demo1).flickable(scrollNext);}); $(.prev).click(function() { $(#demo1).flickable(scrollPrev);}); }); Ten lines of code!!! Ho my, I love micro-frameworks. If you want to discover more micro-frameworks, visit this website: http://microjs.com/

get the source code

Review and download the source code of this article on github: https://github.com/michaelchaize/appliness/tree/master/zepto-flickable-sample Discuss and exchange about this article with the Appliness community experts:

http://www.appliness.com/forums/topic/zepto-and-touch-gestures/

9/9

appliness

DONT WORRY, BE APPLI

A closer look at Underscore templates

Underscore.js is a highly useful complement to JavaScripts rather sparse standard library. In a pinch, Underscore gives you simple templating, too. This ARTICLE explains how it works and gives tips.

Preliminaries
All interactions in this post are done in the Node.js REPL (Read-Eval-Print-Loop). The REPL provides a way to interactively run JavaScript and see the results. It can be used for debugging, testing, or just trying things out. It has the advantage of Underscore.js being easy to install: npm install underscore The only drawback is that you cant use the name _ in the REPL. You need to use a name such as u: > var u = require(underscore); In modules, you can use the name _ and in the following examples, we pretend that that is possible in the REPL, too.

ou Playgr

nd

- Templates - Mustache - Node

Difficulty
- rookie - intermediate - expert

Todo list

- install node - clean code

- structure

by Axel Rauschmayer

Working with Underscore templates


The template function has the following signature: _.template(templateString, data?, settings?) templateString holds the template. settings allow you to override the global settings. If you omit data, you compile a template that has to be applied to data as a function: > var t1 = _.template(Hello <%=user%>!); > t1({ user: <Jane> }) // insert data Hello <Jane>! // compile

First, you compile a template function t1, then you use that function to produce a string. You can also specify the parameter data and directly insert it into the template, without an extra compilation step: > _.template(Hello <%=user%>!, { user: <Jane> }) Hello <Jane>!

Inserting data
Data can be inserted dynamically in three ways: <%=interpolate%> Insert the result of an expression. The properties of the data object are all available as variables (see property user, above). No escaping happens, values are inserted verbatim. <%-escape%> Insert the result of an expression, but escape the following characters via _.escape(): &<>/ Example: > _.template(Hello <%-user%>!, { user: <Jane> }) Hello &lt;Jane&gt;! <%evaluate%> Evaluate the given code. This allows you to do loops and conditions (see next section).

Loops and conditions


The escape directive lets you insert arbitrary code. In the following template, we iterate over an array of names that is stored in property users: var t2 = _.template( Users: <%_.forEach(users, function (u) {%> + <%=u%>, + <%})%> );

2/6

t2 is used as follows. > t2({ users: [ Huey, Dewey, Louie ]}) Users: Huey, Dewey, Louie, By referring to the index of the current element, you can avoid the trailing comma: var t2 = _.template( Users: <%_.forEach(users, function (u,i) {%> + <%if (i>0) {%>, <%}%> + <%=u%> + <%})%> ); Interaction: > t2({ users: [ Huey, Dewey, Louie ]}) Users: Huey, Dewey, Louie

Printing content
You can use the print function to imperatively insert content. For example, the previous example could be rewritten as follows: var t2 = _.template( Users: <%_.forEach(users, function (u,i) {%> + <%if (i>0) { print(, ) }%> + <%=u%> + <%})%> );

3/6

Referring to the data object


You can also refer to the properties of the data object via that object, instead of accessing them as variables. Example: The following two expressions are equivalent. _.template(Hello <%=user%>!, { user: <Jane> }) _.template(Hello <%=obj.user%>!, { user: <Jane> }) Using obj makes it easier to check whether a property exists. Compare the following two templates are equivalent. <%if (typeof title !== undefined) {%>Title: <%=title%><%}%> <%if (obj.title) {%>Title: <%=title%><%}%> The variable holding the data object is obj by default, but can be configured. Below, we use the name data, instead. _.template(<%if (data.title) {%>Title: <%=title%><%}%>, null, { variable: data }); If you specify a variable name in this manner, the properties of data wont be available as variables. That has the advantage that Underscore wont have to use a with statement and the template function will be faster.

Passing meta-data to a template


Sometimes, you want to hand meta-data to the template that is independent of the data to be displayed. Example: You iterate over objects, apply a template to each one and want to tell that template when to show a separator. There is no direct way of doing this, but you can extend the data with the meta-data: var tmpl = _.template(...); _.forEach(objects, function (obj, index) { tmpl(_.extend({ _showSeparator: index > 0 }, obj)); });

Changing the syntax


The settings (global or per-template) allow you to change the syntax for inserting data. For example, you can use Mustache-style curly braces instead of angle brackets: _.templateSettings = { interpolate : /\{\{(.+?)\}\}/g }; Interaction: > _.template(Hello {{user}}!, { user: <Jane> }) Hello <Jane>!
4/6

You can change the syntax of each kind of insertion. Note, though, that syntax will be handled in the order escape, interpolate, evaluate. Hence, you cannot use more specific syntax for a later kind. For example, additionally introducing {{!...}} for evaluation would not work, because it would be preempted by interpolation.

Pre-compilation
You have the option to compile a template once, in advance, instead of doing so many times in the clients. Each compiled template function has the property source which holds the source of that function. The following is a fragment of server-side template that is used to produce a web page. The result could be stored or cached somewhere. ... <script> var clientTmpl = <%= _.template(clientTmplDef).source %>; </script> ... One of the parameters of the above server-side template is the property clientTmplDef which holds the definition of a client-side template.

The internals
Compiling a template works as follows: The given template string is transformed to JavaScript code which is then evaluated into a function. For example: _.template(templateString) The above template is compiled to the function function (obj) { var __p = []; // (Some code omitted here) with (obj || {}) { __p.push(templateString); } return __p.join(); } Lets look at a more complex example that shows you how insertion works: _.template(a <%-esc%> b <%=inter%> c <%eval%> d); Compiled into a function: function (obj) { var __p = []; function print() { __p.push.apply(__p,arguments); }

5/6

with (obj || {}) { __p.push(a , _.escape(esc), b , inter, c ); eval; __p.push( d); } return __p.join();

Style
Underscores templates are very simple. Their disadvantage is that they always look a bit ugly. Their advantage is that they are dead-simple to understand once youve got the basics figured out. In other templating languages, you have to learn the syntax for loops etc. With Underscore templates, you simply use JavaScript syntax. That also means that you should embrace this rather imperative templating style and not try to make it declarative. If you want something more declarative, take a look at alternatives such as Mustache. For debugging, the aforementioned property source is very useful.

CONCLUSION
This article explained how Underscores templates work. In many projects, Underscore is already there, which means that you dont need a more sophisticated templating engine if your needs are simple.

ABOUT THIS ARTICLE


Dr. Axel Rauschmayer is a and trainer for JavaScript, nologies and information ment. He blogs at 2ality.com rently writing a book on http://www.2ality.com/ @rauschma consultant web techmanageand is curJavaScript.

ONLINE RESOURCES His blog http://2ality.com His book http://www.jsguide.org/ Underscore.JS http://underscorejs.org/

appliness

DONT WORRY, BE APPLI

Writing an AngularJS App with an Express + Node.js Backend

LEARN HOW TO BUILD A SIMPLE CRUD APPLICATION WITH ANGULARJS, A POWERFUL FRAMEWORK TO BUILD DATA DRIVEN APPLICATIONS. AngularJS lets you extend HTML vocabulary for your application. The resulting environment is extraordinarily expressive, readable, and quick to develop.

DISCOVER ANGULAR
AngularJS is like the missing Batarang on your utility belt of web development awesomeness. It gives you two-way data binding thats both easy to use and fast, a powerful directive system that lets you use create reusable custom components, plus a lot more. Express is an excellent webserver for Node.js that provides routing, middleware, and sessions. Incidentally, the two work quite well together! In this tutorial, Im going to walk through writing a simple blog app with Angular and Express. For this, Im assuming basic TAP TO PLAY THE VIDEO knowledge of Angular and Node. If youre new to Angular, I highly recommend that you check out the AngularJS homepage first or watch the Hello World tutorial with AngularJS video.

ou Playgr

nd

Difficulty
- rookie - intermediate - expert

- NodeJS - AngularJS - Jade

Todo list
- JSON

- tamplates - binding

by Brian Ford

FINAL APPLICATION
If youd rather skip to the end and see the finished product, you can grab the finished product from Github, or take a look at a live demo here:

This application is really divided into two parts: client, and server. The client runs on the web browser, and does asynchronous communication to the server. The server then retrieves and stores data for the client. For this app, well use AngularJS to build the client and Express to build the server.

Getting the Angular Express Seed


To kick start the process of writing an AngularJS app, Ive created the Angular Express Seed, based on the Express web server (which runs on Node.js) and the Angular Seed. To get started, you can either clone the angular-node-seed repo from Github: git clone git://github.com/btford/angular-express-seed my-project or download it as a zip. Once you have the seed, you need to grab a few dependencies with npm. Open a terminal to the directory with the seed, and run: npm install
2/10

With these dependencies installed, you can run the skeleton app via: node app.js and pointing your browser to http://localhost:3000.

Building the AngularJS client


Well start by defining some views and client-side behavior, then writing a JSON API that our AngularJS client can interact with. First, were going to write some views using Jade. Jade is a template language that integrates well with Express. It lets you write HTML more concisely. For example, this Jade: doctype 5 html(lang=en) head title= pageTitle body h1 Jade - node template engine #container p This is a paragraph Will compile to this HTML: <!DOCTYPE html> <html lang=en> <head> <title>Jade</title> </head> <body> <h1>Jade - node template engine</h1> <div id=container> <p>This is a paragraph</p> </div> </body> </html> An important note here is that while Jade lets you do interpolation via #{someVar}, were going to reserve interpolation for AngularJS to take care of on the client so can take advantage of the two-way data binding that Angular provides. Nevertheless, Jade is an awesome HTML preprocessor, and takes a lot of the typing out of writing views. Open views/index.jade and replace the contents with: extends layout block body div h2 My Blog ul li

3/10

li

a(href=/) Home a(href=/addPost) Add a new post

div(ng-view) script(src=js/lib/angular/angular.js) script(src=js/app.js) script(src=js/services.js) script(src=js/controllers.js) script(src=js/filters.js) script(src=js/directives.js) The first few lines tell Express to wrap the boilerplate template in views/layout.jade around our view. Then we have a header, followed by a navigation bar, and finally a placeholder for Angular views. Next, well add views for each of the basic functions: reading a list of short summaries of posts, reading a full-length post, editing a post, or deleting a post. Create a new file, views/partials/index.jade: p There are {{posts.length}} posts div(ng-repeat=post in posts) h3 {{post.title}} div {{post.text}} a(href=readPost/{{post.id}}) More | a(href=editPost/{{post.id}}) Edit | a(href=deletePost/{{post.id}}) Delete This is a pretty straightforward view: it displays the number of posts at the top, then iterates through each post creating a div for each one, with links to read the full post, edit it, or delete it. Lets create a few more views. The first is for reading a full post on its own page: views/partials/ readPost.jade h3 {{post.title}} div {{post.text}} One for adding a new post: views/partials/addPost.jade h2 Write a new post label(for=title) Title: input(ng-model=form.title, name=title) p Body: textarea(ng-model=form.text, cols=50, rows=15) p button(ng-click=submitPost()) Submit Post One for editing an existing post: views/partials/editPost.jade h2 Edit post label(for=title) Title: input(ng-model=form.title, name=title) p Body: textarea(ng-model=form.text, cols=50, rows=15) p

4/10

button(ng-click=editPost()) Edit Post Lastly, a view for deleting a post: views/partials/deletePost.jade h2 {{post.title}} div {{post.text}} p | Are you sure you want to delete this post? button(ng-click=deletePost()) Yes | button(ng-click=home()) No thanks Now we need to connect these views to controllers. Open public/js/app.js and modify it accordingly: // Declare app level module which depends on filters, and services angular.module(myApp, [myApp.filters, myApp.services, myApp.directives]). config([$routeProvider, $locationProvider, function($routeProvider, $locationProvider) { $routeProvider. when(/, { templateUrl: partials/index, controller: IndexCtrl }). when(/addPost, { templateUrl: partials/addPost, controller: AddPostCtrl }). when(/readPost/:id, { templateUrl: partials/readPost, controller: ReadPostCtrl }). when(/editPost/:id, { templateUrl: partials/editPost, controller: EditPostCtrl }). when(/deletePost/:id, { templateUrl: partials/deletePost, controller: DeletePostCtrl }). otherwise({ redirectTo: / }); $locationProvider.html5Mode(true); }]); This routing configuration will also let the app use the HTML5 push/pop history API. Were almost done with the client side of the app. The last thing we need is the set of controllers to make requests to our server. Open public/js/controllers.js: function IndexCtrl($scope, $http) { $http.get(/api/posts). success(function(data, status, headers, config) {

5/10

$scope.posts = data.posts; });

function AddPostCtrl($scope, $http, $location) { $scope.form = {}; $scope.submitPost = function () { $http.post(/api/post, $scope.form). success(function(data) { $location.path(/); }); }; } function ReadPostCtrl($scope, $http, $routeParams) { $http.get(/api/post/ + $routeParams.id). success(function(data) { $scope.post = data.post; }); } function EditPostCtrl($scope, $http, $location, $routeParams) { $scope.form = {}; $http.get(/api/post/ + $routeParams.id). success(function(data) { $scope.form = data.post; }); $scope.editPost = function () { $http.put(/api/post/ + $routeParams.id, $scope.form). success(function(data) { $location.url(/readPost/ + $routeParams.id); }); };

function DeletePostCtrl($scope, $http, $location, $routeParams) { $http.get(/api/post/ + $routeParams.id). success(function(data) { $scope.post = data.post; }); $scope.deletePost = function () { $http.delete(/api/post/ + $routeParams.id). success(function(data) { $location.url(/); }); }; $scope.home = function () { $location.url(/); };
6/10

The controllers are all relatively straightforward: they make calls to $http to communicate with the server, and attach methods to the controllers scope to allow the corresponding view to make additional requests on a button click. Lets look at EditPostCtrl alongside its view, views/partials/editPost.jade for example: function EditPostCtrl($scope, $http, $location, $routeParams) { $scope.form = {}; $http.get(/api/post/ + $routeParams.id). success(function(data) { $scope.form = data.post; }); $scope.editPost = function () { $http.put(/api/post/ + $routeParams.id, $scope.form). success(function(data) { $location.url(/readPost/ + $routeParams.id); }); };

h2 Edit post label(for=title) Title: input(ng-model=form.title, name=title) p Body: textarea(ng-model=form.text, cols=50, rows=15) p button(ng-click=editPost()) Edit Post When the controller loads, it makes a request to /api/post/{{$routeParams.id}}, which it uses to populate $scope.title and $scope.text. Then, it attaches a method editPost to the local scope, which sends a POST request to the server which contains the id of the post to edit and the updated title and text. In editPost.jade, the input and textarea have ng-model attributes that setup data binding, and we attach $scope.editPost() to a button so that it fires when the button is pressed.

Building the JSON server with Express


Typically, youd connect to some database and store/load your data from there, however for this example app Im just going to use an in-memory object. Express has an excellent way to respond with JSON rather than HTML through res.json. Open routes/api.js and replace the contents with: // initialize our faux database var data = { posts: [ { title: Lorem ipsum, text: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. }, {

7/10

title: Sed egestas, text: Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing , commodo quis, gravida id, est. Sed lectus. } ] }; // GET exports.posts = function (req, res) { var posts = []; data.posts.forEach(function (post, i) { posts.push({ id: i, title: post.title, text: post.text.substr(0, 50) + ... }); }); res.json({ posts: posts }); }; exports.post = function (req, res) { var id = req.params.id; if (id >= 0 && id < data.posts.length) { res.json({ post: data.posts[id] }); } else { res.json(false); } }; Well continue adding code to this file to handle adding, editing, and deleting posts: // POST exports.addPost = function (req, res) { data.posts.push(req.body); res.json(req.body); }; // PUT exports.editPost = function (req, res) { var id = req.params.id; if (id >= 0 && id < data.posts.length) { data.posts[id] = req.body; res.json(true); } else { res.json(false); }
8/10

};

// DELETE exports.deletePost = function (req, res) { var id = req.params.id; if (id >= 0 && id < data.posts.length) { data.posts.splice(id, 1); res.json(true); } else { res.json(false); }

};

Next, we have to connect these routes to the appropriate requests. Open app.js, and below the app configuration, add this code under the //Routes comment: /** app init & config... */ // Routes app.get(/, routes.index); app.get(/partials/:name, routes.partials); // JSON API app.get(/api/posts, api.posts); app.get(/api/post/:id, api.post); app.post(/api/post, api.addPost); app.put(/api/post/:id, api.editPost); app.delete(/api/post/:id, api.deletePost); /* ... */ The first route takes care of serving our main page that runs the angular app. The next route lets Angular load partials on demand. The following routes establish our JSON API, linking http://yourapp.com/api/ posts to the posts route, http://yourapp.com/api/addPost to the addPost route, and so on. Notice the :id on line 13: thats a parameter parsed out of the URL by Express. Why dont the bottom three routes have that parameter, then? The reason is because its better to do a POST rather than a GET to avoid cross-site scripting. In general, when requesting information, use GET, but when invoking some action, use POST. Start up the app as we did with the skeleton earlier: node app.js You should be able to add, update, read, and delete posts.

CONCLUSION
Writing apps with AngularJS and Express is both fun and easy. Both frameworks let you dive right into the business logic of your app without much boilerplate, so in just a few hundred lines, were able to write

9/10

a complete (albeit simple) app. Maintaining a clear distinction between client and server makes the app easier to maintain and test. In a future post, Ill cover how to test an app built on Angular and Express. There are a lot of other possible improvements to this blog. Youll notice some flickering between loads. AngularJS provides ways to address this issue, but thats outside of the scope of this post. A real blog application would also probably want posts to have some notion of formatting, which is also achievable using some of Angulars more advanced features. I also hope to address these things in subsequent articles.

get the source code

Review and download the source code of this article on github:

https://github.com/btford/angular-express-seed
Discuss and exchange about this article with the Appliness community experts:

http://www.appliness.com/forums/topic/writing-an-angularjs-app-with-an-express-node-js-backend/

ABOUT THIS ARTICLE


Brian Ford is a student at the University of Michigan and hacks on the web in his free time. His current interests are all things JavaScript, but most notably Node.js. Hes currently interning at Google to work on AngularJS. http://briantford.com @briantford

ONLINE RESOURCES AngularJS http://angularjs.org/ ExpressJS on NodeJS http://expressjs.com/ Jade templating engine http://jade-lang.com/

appliness

DONT WORRY, BE APPLI

JAVASCRIPT PROTOTYPAL INHERITANCE FOR CLASSICAL DEVELOPERS

Developers who are learning JavaScript and have prior experience with strongly typed classical languages like Java, C#, or C++ often have trouble using the JavaScript inheritance model. Some even think that JavaScript doesnt support inheritance - at least thats what I thought when I first learned it. Well, I was completely wrong!

A couple of days ago I started the process of componentization for a part of an app that I was working on. During that task, I wanted to remove a reference to Backbone.js, which mimics the classical inheritance model in JavaScript. Because of that, I had to dig deeper than before to understand how I could use pure prototypal inheritance without any third-party frameworks or libraries. So below, you can see a solution that I discovered on many blogs, forums, and other docs covering this topic. I believe this is the cleanest solution that doesnt require any third-party code to include in your apps. The snippet below defines a base Parent type that other types in the following snippets will inherit from. It is specified as a function that will be a constructor for a new objects. It also specifies a funA function that can be overridden in descendent types. // ******* DEFINING PARENT TYPE ******* var Parent = function(a) { // Setting type instance level properties this.a = a; };

d n u o laygr

5 t p i r c S A - ECM - rookie - HTML5 - intermediate t p i r c S a v a - J - expert

Difficulty

Todo list

- inheritance - constructors - override

by Piotr Walczyszyn

// Defining funA function that will be inherited by descendant types Parent.prototype.funA = function() { // Parent.funA code... }; The snippet below defines a Child type that inherits from Parent type. The inheritance is done in two steps, first by calling the Parent constructor function using Parent.call(this, a) and second, by setting the prototype property to a new object with a prototype property from the Parent type (in this case I used the new Object.create() function that is specified in ECMAScript5; IMHO this approach is preferable to creating a new instance of Parent type because this way the Parent type constructor function is not called unnecessarily). // ******* DEFINING CHILD TYPE ******* var Child = function(a, b) { // Calling parent type constructor function Parent.call(this, a); // Setting type instance level properties this.b = b;

};

// This will give Child access to Prent functions // Object.create() function requires ECMAScript5 compatible browser, // if this is not supported just a new instance of Prent type could be used instead Child.prototype = Object.create(Parent.prototype); // Defining funB that will be only available for Child type instances Child.prototype.funB = function() { // Child.funB code... }; This last snippet demonstrates how you can override ancestor functions; in this case the funA function is overridden. The GrandChild.funA() implementation demonstrates also how to make calls to the ancestor type funA function. // ******* DEFINING GRANDCHILD TYPE ******* var GrandChild = function(a, b, c) { // Calling parent type constructor function Child.call(this, a, b); // Setting type instance level properties this.c = c;

};

// This will give GrandChild access to Parent and Child functions through a prototypes chain GrandChild.prototype = Object.create(Child.prototype); // Overriding ParentType.funA function GrandChild.prototype.funA = function() { // Calling overridden funA function Parent.prototype.funA.call(this);

2/3

}; Hope this will be useful for those of you who are switching from a classical inheritance model. One last comment and some advice for those that like to bash JavaScript for different things. Before doing so, first try to understand how prototypal languages work and dont try to use them in a way they were not designed to work. If you want to experiment further with the example above you can check it out on JSFiddle.

// GrandChild.funA code...

MORE INFORMATION

>

ABOUT THIS ARTICLE


Piotor Walczyszyn is a technology geek living in Warsaw, Poland. outof.me is his new blog in which he wants to express his current interests and share some of his work. He works for Adobe as a Developer Evangelist which he finds exciting and fun. http://outofme.com/ @pwalczyszyn

ONLINE RESOURCES HTML5Rocks website http://www.html5rocks.com/en/ JSFiddle http://jsfiddle.net/ ECMAScript http://www.ecmascript.org/

>

appliness

DONT WORRY, BE APPLI

Prototypal Inheritance & Strategies for Debugging Tough Problems

I recently ran into an issue on app-UI where child views were having their touch/ mouse event listeners removed once another view was pushed onto the stack in the ViewNavigator component.

f you havent seen it yet, app-UI is a collection of reusable application container components for building native-like mobile experiences for apps built with web technologies. It is still in the very early stages of development, and Im actively working on it so please let me know if you run into any issues or suggestions.

I scoured through all of my application and framework code, but just couldnt seem to figure out why/where event listeners were being removed. What I needed to do was simple, figure out where removeEventListener was being invoked. removeEventListener is a native function, so you cant set a breakpoint to see every instance where it is being invoked, right?

Actually, you can, but you have to look at the problem just a bit differently You cant set a breakpoint on a native function; however, since JavaScript uses prototypal inheritance you can change the prototype of an object to change its behavior and override native functions. Since you can modify an object prototype, changes to that objects prototype will be applied to all instances of that object type. So, you can add some debugging code to override the behavior of HTMLElements removeEventListener function.

d n u o laygr

- Backbone - rookie s .j e r i u q e R - intermediate e l i b o M y r e - jQu - expert

Difficulty

Todo list

- modules - MVC

- mobile dev

by Andy Trice

First, make a copy of the original removeEventListener function on the HTMLElement.prototype: HTMLElement.prototype.originalRemoveEventListener = HTMLElement.prototype.removeEventListener Next, override the original removeEventListener function, add a console.log() statement, and then invoke the original removeEventListener function that you just made a copy of: HTMLElement.prototype.removeEventListener = function(type, listener, useCapture) { console.log(remove: + type); this.originalRemoveEventListener(type, listener, useCapture); }; Now, every time that the HTMLElements removeEventListener function is invoked, you will get a console. log() statement. Not only do you get console debugging, but you can now set a breakpoint inside of the new, overridden, removeEventListener function. Using the breakpoint, you can use your developer tools to view the call stack and track down where the removeEventListener function is being invoked. Thus, you can track down the root of your issue. I use the Chrome developer tools, but similar tools are also available in Safari, FireFox, IE, and Opera. Using the call stack, I was able to track down that I was inadvertently calling jQuerys remove() function on the views DOM element, instead of jQuerys detach() function. Both remove() and detach() will remove your elements from the pages DOM, however remove() also gets rid of any event listeners to prevent memory leaks. When I made the one-line code change from remove() to detach(), everything resumed working as expected. I then removed the debugging code. Heres the complete code in one snippet for overriding removeEventListener: HTMLElement.prototype.originalRemoveEventListener = HTMLElement.prototype.removeEventListener;t HTMLElement.prototype.removeEventListener = function(type, listener, useCapture) { console.log(remove: + type); this.originalRemoveEventListener(type, listener, useCapture); }; Prototypal inheritance gives you the ability to change the behavior of objects at runtime, and it can be incredibly powerful in building your HTML/JS applications.

MORE INFORMATION

>

ABOUT THIS ARTICLE


Andy Trice is a Technical Evangelist for Adobe Systems. Andrew brings to the table more than a decade of experience designing, implementing, and delivering RIA for the web, desktop, and mobile devices. http://tricedesigns.com/ @andytrice

ONLINE RESOURCES JQuery Mobile official website http://jquerymobile.com/ JQuery UI http://jqueryui.com/ app-UI https://github.com/triceam/app-UI/issues

>

appliness

DONT WORRY, BE APPLI

Improving geolocation

DIscover how to improve geolocation.getCurrentPosition() with getAccurateCurrentPosition(), my LATEST javascript library

BACKGROUND
getAccurateCurrentPosition() is a simple enhancement to navigator.geolocation that provides a more accurate and predictable result. It is intended for any geolocation-enabled web browser. This is also usable in PhoneGap applications since PhoneGap uses the underlying HTML geolocation APIs already. I have tested this on desktop Chrome, Safari, Firefox and on iOS and Android devices. I have not tested on IE9+ or Opera or Windows devices. navigator.geolocation provides the method geolocation.getCurrentPosition() that will return the current location of the device. This seems easy enough so most developers simply call this method when they need the location. One of the options for this method is enableHighAccuracy, which obviously implies that you need an accurate location. However, I soon discovered that if the devices GPS has not been used recently in the current location, it will take a while for it to acquire a decent location. The getCurrentPosition() success callback will trigger before the phones GPS hardware can provide anything accurate. In other words, you get a quick response, but not necessarily an accurate response. In my own testing with an iPhone 4s and an HTC Inspire, when I would check getCurrentPosition() on the device, I would sometimes get an accuracy of over 1000 meters. Basically, the first location to be acquired is what is passed to the callback. What if you need more accuracy? You can re-call getCurrentPosition()

ou Playgr

nd

Difficulty
- rookie - intermediate - expert

- GPS - Timer - Watch

Todo list
- locate - refine - call the FBI
by Greg Wilson

and likely better accuracy because the GPS has had more time to acquire satellites, but how many times will you need to call it? A better way to do this is to use navigator.geolocation.watchPosition(). This method will do a callback every time the location changes or every time the device improves the accuracy (based on my observations). In my own testing with a freshly booted device, it will take between 2 and 6 callbacks to get to something highly accurate. This led me to write this very simple JavaScript function that uses watchPosition() in combination with a simple timer. The option parameters are identical to getCurrentPosition() with the following additions: - desiredAccuracy: The accuracy in meters that you consider good enough. Once a location is found that meets this criterion, your callback will be called. - maxWait: How long you are willing to wait (in milliseconds) for your desired accuracy. Once the function runs for maxWait milliseconds, it will stop trying and return the last location it was able to acquire. NOTE: If the desired accuracy is not achieved before the timeout, the onSuccess is still called. You will need to check the accuracy to confirm that you got what you expected. I did this because its a desired accuracy, not a required accuracy. You can of course change this easily. The following params also exist for getCurrentPosition() but are set for you in getAccurateCurrentPosition(): - timeout: If no timeout is specified, it will be set to the maxWait value - enableHighAccuracy: This is forced to true (otherwise, why are you using this function?!)

sample usage
//getting an acurate position navigator.geolocation.getAccurateCurrentPosition(onSuccess, onError, {maximumAge:10000, desiredAccuracy:20, maxWait:15000}); Translating the above options into English: This will attempt to find the device location with an accuracy of at least 20 meters (ignoring any location that was cached by the device more than 10 seconds ago) and it will work for 15 seconds to achieve this accuracy.

get the source code


Review and download the source code of this article on github: https://github.com/gwilson/getAccurateCurrentPosition/blob/master/geo.js Discuss and exchange about this article with the Appliness community experts:

http://www.appliness.com/forums/topic/improving-geolocation/

appliness

DONT WORRY, BE APPLI

BUILD A CHAT WITH NODE.JS AND JQUERY MOBILE

if you plan to simply add collaborative features to your web applications then read this tutorial. I will show how to build a chat using modern web technologies such as jquery mobile, node, websockets and heroku.

the web architecture


The web platform can also host real-time experiences such as MMO games or Enterprise collaborative experiences. Although its still being standardized by the W3C, WebSockets are more and more implemented to synchronize web user interfaces. It provides a full-duplex communication API to enable bi-directional communications. In this article, youll learn how to build a simple chat using several modern web technologies and platforms: - jQuery Mobile is used to build the UI - Socket.IO is the JavaScript library that will create and catch real-time messages on the client-side but also on your server. - NodeJS will be used on the server side to catch and broadcast the JavaScript messages. Im using Heroku to host the application as it provides by default a NodeJS development environment.

I wont explain how to setup a Heroku instance. You just have to know that

ou Playgr

nd

- Node.JS - jQM - Socket.io

Difficulty
- rookie - intermediate - expert

Todo list

- connect - dispatch

- feed the cat

by Michal Chaize

its free for developers and that it takes a few minutes to get an environment up and ready.You can use the Cedar stack of Heroku (the default runtime stack) and get Node.js and the Express web framework installed. Read this tutorial to setup your Heroku application: https://devcenter.heroku.com/articles/nodejs

TEST THE APPLICATION


To test the chat, you can play with the following interactive sample of this page and also launch another browser instance on your computer for instance. Enter a username on the first screen, tap the submit message and youll enter the chat room. The chat is hosted on Heroku and the URL is:

http://warm-samurai-5416.herokuapp.com/

2/7

BUILD The UI with jQuery Mobile


The application is composed with two screens. The first screen is welcoming the user and asks for a username. When the user taps Submit, it will launch a transition to the second screen which is the chat room. The second screen starts with a text input field to type a message, a Send button, and a simple HTML list <ul> to display the messages that are dispatched by the chat server.

Once the jQuery and jQuery Mobile libraries imported in your HTML page, you just have to declare <DIV> elements and assign data-role attributes to define the structure of these two screens. In this sample application, you can define the two pages in one single HTML file as the structure of the application is super easy. <body> <div data-role=page id=loginPage> <div data-role=header data-position=fixed> <h1>Welcome on my chat</h1> </div><!-- /header --> <div data-role=content> <div id=formLogin> <p> <label for=usertext>Please enter your username:</label> <input type=text id=usernameText/> </p> <a href=#chatPage data-role=button>Submit</a> </p> </div> </div> </div> <div data-role=page id=chatPage> <div data-role=header data-position=fixed> <h1>Lets chat</h1> </div> <div data-role=content> <div> <label for=messageText>Your message</label> <input type=text id=messageText/> <button id=sendButton >Send</button> </div> <div class=listDiv> <ul id=messages data-role=listview> </ul> </div>
3/7

<p>

</div> </div> </body>

introduction to Socket.IO
Socket.io is a fantastic JavaScript library that makes real-time applications possible in web browsers and mobile devices. Depending on the user configuration, it will chose the best technology to transport the messages, starting with Flash, and ending with HTML5 WebSockets when available. It relies on NodeJS on the server side and you can use the port 80 to transport messages and pass through all the firewalls. Using Node.JS, you can directly call the command npm install socket.io Once installed, here is a basic Hello World application using Socket.io: SERVER (APP.JS) var app = require(http).createServer(handler) , io = require(socket.io).listen(app) , fs = require(fs) app.listen(80); function handler (req, res) { fs.readFile(__dirname + /index.html, function (err, data) { if (err) { res.writeHead(500); return res.end(Error loading index.html); } res.writeHead(200); res.end(data); });

io.sockets.on(connection, function (socket) { socket.emit(news, { hello: world }); socket.on(my other event, function (data) { console.log(data); }); }); CLIENT (INDEX.HTML) <script src=/socket.io/socket.io.js></script> <script> var socket = io.connect(http://localhost); socket.on(news, function (data) { console.log(data); socket.emit(my other event, { my: data }); }); </script>

4/7

server side application


You can use the Express web framework on Heroku. Express is a standard module of Node.JS for web development. You usually starts with the creation of the Express server, you can use the routing features of Express to redirect the users and mount new applications. Its very robust and performant. The classic implementation of Express looks like this: var app = express.createServer(); app.get(/, function(req, res){ res.send(Hello World); }); app.listen(3000); Here the code deployed on Heroku to manage the messages of the chat on the server side (in the nodeJS application): var express = require(express); var app = express.createServer(express.logger()), io = require(socket.io).listen(app); io.configure(function () { io.set(transports, [xhr-polling]); io.set(polling duration, 10); }); app.get(/, function(request, response) { response.sendfile(__dirname + /index.html); }); var port = process.env.PORT || 3000; console.log(Listening on + port); app.listen(port); io.sockets.on(connection, function (socket) { socket.on(message, function (data) { console.log(message on server);

socket.broadcast.send(data); }); }); When a user will launch your application, he will be redirected to index.html (which contains your jQuery Mobile application): app.get(/, function(request, response) { response.sendfile(__dirname + /index.html); });

5/7

Notice that Heroku doesnt authorize the usage of WebSockets for the moment. The stack supports Socket.IO, however the following configuration settings are necessary to force long polling and prevent the use of WebSockets. io.configure(function () { io.set(transports, [xhr-polling]); io.set(polling duration, 10); }); The io object is listening at events. The io.sockets connection is used to initialized the message broker and to defines whats happening when a message is received (socket.on message). In a chat application, you need to broadcast the received messages to all the users connected to the server. Thats why you need to add the broadcast flag to the send method calls. Broadcasting means sending a message to everyone else except for the socket that starts it. io.sockets.on(connection, function (socket) { socket.on(message, function (data) { console.log(message on server);

socket.broadcast.send(data); }); }); This is very basic. You can improve the server application adding sending and getting data acknowledgements, or define volatile messages. Check the samples on the Socket.io pages to discover all the possibilities of this framework: http://socket.io/#how-to-use

CLIENT-side javascript
First, you need to import the Socket.io JavaScript library in index.html: <script src=/socket.io/socket.io.js></script> Once the document is ready, you can create a socket and connect it to your Heroku application: $(document).ready(function() { var socket = io.connect(http://warm-samurai-5416.herokuapp.com/); When the server broadcasts a message, you can log it and display its content in the list using jQuery. socket.on(message, function(message) { $(#messages).append(<li> + message + </li>); $(#messages).listview(refresh); });

6/7

A disconnect event is also available. socket.on(disconnect, function() { $(#messages).append(<li>Disconnected from the server.</li>); }); Youre building a chat, so the client is also supposed to create and send messages. Build your message using jQuery. In this sample, a message contains the current date, a name and a text message. The function getDisplayMessage() returns a formatted string: function getCurrentDate(){ var currentTime = new Date(); var hours = currentTime.getHours(); var mins = currentTime.getMinutes(); var secs = currentTime.getSeconds(); return(hours + :+ mins + : + secs); } function getDisplayMessage(){ var message = $(#messageText).val(); var userName = $(#usernameText).val(); return(<em>+userName + ( + getCurrentDate() +)</em>: + message); } Then you can use the send() method of your socket object. As the server will broadcast the message to all the users except yourself, you need to display the message in the list yourself using jQuery and clear the text input field: $(#sendButton).bind(click, function() { socket.send(getDisplayMessage()); $(#messages).append(<li class=mySelf> + getDisplayMessage() + </li>); $(#messages).listview(refresh); $(#messageText).val(); });

get the source code

Review and download the source code of this article on github:

https://github.com/michaelchaize/appliness/tree/master/chat-jqm-heroku-node
Discuss and exchange about this article with the Appliness community experts:

http://www.appliness.com/forums/topic/build-a-chat-with-node-js-and-jquerymobile/

appliness

DONT WORRY, BE APPLI

Building PhoneGap applications powered by Database.com

In this article we will explore the creation of mobile applications built using PhoneGap, with all data served and persisted using Database.com. Before we dive deeper into the technical details, lets review the terminology.

PhoneGap
PhoneGap is a free and open source technology that enables developers to create natively installed mobile applications on multiple platforms using traditionally web-based technologies. The best way to think of PhoneGap is a web view that takes up the devices full width and height. Within the web view, you build your application interface using HTML, CSS, and JavaScript

d n u o laygr

- PhoneGap m o .c e s a b a t - Da - Cordova

Difficulty
- rookie - intermediate - expert

Todo list

- modules - MVC

- mobile dev

by Andy Trice

The applications web view is based upon the native web view of the operating system, essentially the same as the standard web browser minus the window chrome. You build all of the navigation and content elements entirely in HTML, CSS, and JavaScript, with your application logic written in JavaScript. PhoneGap provides a JavaScript-to-native bridge. This lets your application interact with the native operating system without having to write any native code. You build your application logic entirely in JavaScript, and leverage the PhoneGap API to interact with the device operating system.

Figure 2. PhoneGap provides access to device features

Out of the box PhoneGap provides access to a devices accelerometer, compass, and geolocation capabilities, access to device contacts, the local file system, the device camera, and media playback and capture functionality. You can access all of these features on multiple platforms, without having to write a single line of native code all can be accessed entirely by JavaScript. If this isnt enough for you, you can easily extend PhoneGap by building native plugins on top of the extensible architecture Ill get into further detail later in this article. PhoneGap also provides a means of packaging applications to target popular mobile ecosystems. The output of a PhoneGap application is a binary application archive that contains all necessary HTML, CSS, & JavaScript assets for you application to function.

Figure 3. PhoneGap packages apps to target popular mobile ecosystems

For iOS devices, this outputs an IPA file, for Android this is an APK file, for Windows Phone this is a XAP file, etc All of these binary formats are normal archives that you could then upload to the iTunes Store, Google Play, BlackBerry App World, the Windows Phone Marketplace, or install directly onto a device. A single codebase for a PhoneGap application can be used to target Apple iOS, Google Android, Windows Phone, BlackBerry, HP WebOS, Symbain, and Samsung Bada operating systems, and can be used to target both phone and tablet form factors. As I mentioned earlier, PhoneGap is free and open source. The entire codebase for PhoneGap is freely accessible as a part of the Apache Cordova project. You can download the source, make changes, and contribute back to the project today!

2/22

Database.com
Database.com is the cloud database offering from salesforce.com. Database.com enables hosted relational database capabilities that you easily can tap into within your applications, without having to manage the infrastructure on your own. You can use the Web-based administrative interface to create objects and relationships, and use the REST or SOAP APIs to access your data. You can learn more about the capabilities of Database.com through the Developer Center.

The Application
In this article, we will walk through the creation of a basic PhoneGap application that consumes data from Database.com. Here is the basic concept: It is an application that could be used by workers in the field to travel to various locations and collect contacts or leads. It can be used to gather contact information, as well as notes, and it can record the users GPS coordinates to identify where the information was captured. It will also allow you to go back and edit data that youve previously captured. Of course, the application also needs to be accessible on a variety of platforms. Lets examine the basic flow, then well get into details how it was created.

Figure 4. The sample app three main screens

You can see that there are three main screens, the home screen, which gives you the options to either add a new record or view existing records, the Leads list, which shows existing records, and the form to add/edit records. There will also be a login/authentication screen, which we will cover later, but for now you can see that it is a straightforward application use case. The full source code for this application is available at https://github.com/triceam/Database.ComPhoneGap-Sample.

3/22

Database For data storage, this application will use a single custom table on Database.com. Although this is a basic one-table example, Database.com can also support large, multi-relationship data structures. After you sign up for a free account, log in, and click Create A New Object on the System Overview screen.

Figure 5. Create a new object on the System Overview screen

This will show the New Custom Object dialog. Heres where you enter the label/name for your objects. Here I created an Lead object. To contain the leads that will be captured by the PhoneGap application.

Figure 6. Enter the label/name for your objects

4/22

The next step is to add custom fields to the Lead object. Under the Custom Fields & Relationships section, click on the New button to add data fields.

I added fields for First Name, Last Name, Latitude, Longitude, Notes, Email, and Telephone. Just follow the steps in the online wizard it will guide you through this process.

Figure 7. Add data fields under Custom Fields & Relationships

At this point, weve now created the data objects that will be used to persist data that is captured within the application. However, there is one more step before you can use these objects within a PhoneGap application. In order to access the data data remotely, you must create a remote access application. The configuration of this application will include a unique key that will be used to correctly authenticate users and identify your data objects. To create a new remote access Application, just expand the Develop category and select New.

5/22

Figure 8. Create a new remote access Application in the Develop category

This will display the Remote Access Edit form, where you will need to specify an application name, contact email, and callback URL configuration for your application. The application name will be used as descriptive text when logging into your application, and the callback URL will be used to redirect the users browser once they have authenticated successfully.

Figure 9. Specify the application details in the Remote Access Edit form

Once you save this information, you will be provided with a consumer key, which you will need later when logging in and accessing data services from Database.com. Make a note of your consumer key. You will need this later in your JavaScript configuration.

6/22

Figure 10. The consumer key for logging in and accessing data services from Database.com

Once you have your consumer key, youre ready to start pushing and pulling data in and out of Database. com. Forcetk.js The application will communicate with Database.coms REST API using the forcetk.js JavaScript wrapper. Forcetk.js (Force.com JavaScript REST Tookit) is an open source wrapper to the REST API that simplifies the consumption of data from Force.com/Database.com inside of JavaScript-based applications. Forcetk. js provides the hooks for OAuth2 authentication, and helper methods that make retrieving and updating data incredibly easy. When building applications in PhoneGap, you will be able to access the force.com REST API directly without need for a proxy (like you would if you were building a standard browser-based application).

The PhoneGap Application


When leveraging PhoneGap, you create your applications entirely in HTML, CSS, and JavaScript. You can develop these applications in any text editor. It is up to you to decide which approach to use. You can use a simple text editor like TextMate, an HTML editor like Dreamweaver, or a complex IDE like Xcode, Eclipse, or Visual Studio. IDEs like Xcode, Eclipse, or Visual Studio allow you to deploy PhoneGap applications directly onto a device using a USB connection. However, you can also use PhoneGap Build, a cloud-based PhoneGap compiler, which allows you to simply upload your HTML, CSS, and JavaScript code, and it will generate platform-specific binaries for you. Because the application interface is being built using HTML, CSS, and JavaScript, it is possible to leverage existing tools and frameworks to improve developer productivity. This example will leverage the following tools to speed up the developer process: Zepto.js A development accelerator library that provides utility and shortcut functions for creating interactive and dynamic JavaScript experiences. Zepto.js has a jQuery compatible syntax, with a mobilecentric optimizations. Twitter Bootstrap A UI styling library that provides CSS styles and HTML/JavaScript components to make your application feel more like an app instead of just a web page. Mustache.js An easy-to-use templating library that allows you to create HTML templates for use within your dynamic JavaScript applications. Templating enables you to easily separate your HTML UI layer from the application logic written in JavaScript. The first thing to do within the application is create your root HTML file that will be the entry point into the application. All PhoneGap applications start with an index.html file, which is the root of the application. Within the index.html file, I included all of the appropriate libraries, with a blank HTML <body>. The HTML <body> is blank because the entire user interface will be created dynamically by JavaScript. <html> <head> <link rel=stylesheet href=assets/css/bootstrap.css type=text/css /> <link rel=stylesheet href=assets/css/styles.css type=text/css /> <script type=text/javascript src=js/libs/zepto.js></script> <script type=text/javascript src=js/libs/forcetk.js></script> <script type=text/javascript src=cordova-1.7.0.js></script> <script type=text/javascript src=js/libs/ChildBrowser.js></ script> <script type=text/javascript src=js/libs/mustache.js></script> <script type=text/javascript src=js/salesforceWrapper.js></ script>

7/22

<script type=text/javascript src=js/application.js></script> </head> <body></body> </html> When a PhoneGap application is initialized, a deviceready event is dispatched. This event indicates that the contents of the application have been sufficiently loaded, and all PhoneGap APIs have been initialized. document.addEventListener( deviceready, onDeviceReady ); var sfw; function onDeviceReady( event ) { console.log(deviceready); //initialize salesforce wrapper sfw = new SalesforceWrapper();

The first thing that the application does is initialize a JavaScript class that I created called SalesforceWrapper. The SalesforceWrapper class wraps the forcetk.js library to streamline authentication, and includes all of the configuration information needed to access the force.com REST API. In this class, youll need to set the clientID value with the consumer key that you obtained through the Remote Access configuration that was discussed earlier in this article. function SalesforceWrapper() { /* AUTHENTICATION PARAMETERS */ this.loginUrl = https://login.salesforce.com/; this.clientId = YOUR_KEY_GOES_HERE; this.redirectUri = https://login.salesforce.com/services/oauth2/ success; /* CLASS VARIABLES */ this.cb = undefined; //ChildBrowser in PhoneGap this.client = undefined; //forceTk client instance } this.init();

SalesforceWrapper.prototype.init = function() { this.client = new forcetk.Client(this.clientId, this.loginUrl); this.cb = window.plugins.childBrowser; } SalesforceWrapper.prototype.login = function (successCallback) { this.loginSuccess = successCallback; var self = this; self.cb.onLocationChange = function (loc) { if (loc.search(self.redirectUri) >= 0) { self.cb.close(); self.sessionCallback(unescape(loc)); }

8/22

}; self.cb.showWebPage(self.getAuthorizeUrl(self.loginUrl, self.clientId, self.redirectUri)); } SalesforceWrapper.prototype.getAuthorizeUrl = function (loginUrl, clientId, redirectUri) { return loginUrl + services/oauth2/authorize?display=touch + &response_type=token&client_id= + escape(clientId) + &redirect_uri= + escape(redirectUri); } SalesforceWrapper.prototype.sessionCallback = function(loc) { oauthResponse = {}; var fragment = loc.split(#)[1]; if (fragment) { var nvps = fragment.split(&); for (var nvp in nvps) { var parts = nvps[nvp].split(=); oauthResponse[parts[0]] = unescape(parts[1]); } } if (typeof oauthResponse === undefined || typeof oauthResponse[access_ token] === undefined) { console.log(error); } else { this.client.setSessionToken(oauthResponse.access_token, null, oauthResponse.instance_url); if ( this.loginSuccess ) { this.loginSuccess(); } } this.loginSuccess = undefined; } The SalesforceWrapper class simplifies the example from forcetk.js, and enables you to authenticate with a single line of code in your application: sfw.login( setupHomeView ); The login function of the SalesforceWrapper just needs a single parameter a reference to a function that will be invoked once the user has successfully logged in. You may have also noticed that the SalesforceWrapper refers to the ChildBrowser JavaScript class. The ChildBrowser class is part of the ChildBrowser PhoneGap native extension, which is available for iOS, Android, BlackBerry, and Windows Phone. This enables your PhoneGap application to have a child web view, which in this case, is used for authenticating the Force.com API. Once the SalesforceWrapper class is initialized, the Moustache.js templates are initialized. Each template is a separate HTML file that will be used to render the interface, and they must be loaded into memory before they can be consumed.
9/22

var

var templates = { structure:views/structure.html,

};

home:views/home.html, form:views/formView.html, list:views/dataView.html, listItem:views/listItem.html, loaded: 0, requested: 0,

function onDeviceReady( event ) { console.log(deviceready); //initialize salesforce wrapper sfw = new SalesforceWrapper(); //load Mousetache HTML templates for (var key in templates) { (function() { var _key = key.toString(); if ( _key != loaded && _key != requested ){ templates.requested ++; var templateLoaded = function( template ){ onTemplateLoaded( template, _key ); } } })(); $.get( templates[ _key ], templateLoaded );

function onTemplateLoaded(template, key) { console.log( key + : + template); templates[ key ] = template; templates.loaded ++; if ( templates.loaded == templates.requested ) { setupDefaultView(); }

} Once the templates have been loaded, the setupDefaultView() function gets invoked. This sets up the initial user interface, based upon the templates.structure template. var header, container; function setupDefaultView() { console.log(setupDefaultView); $(body).html( templates.structure ); header = $(body).find(#header); container = $(body).find(#content); $(#login).tap(function (e) { e.preventDefault(); sfw.login( setupHomeView );

10/22

});

It then sets a reference to the header and container elements from that template for future usage, then adds an event handler to the login button so that when the user taps the button, the login functionality from the SalesforceWrapper class is invoked. You can view the HTML fro the templates.structure template below: <div id=header>Welcome</div> <div id=content> <h3 style=padding-top:1.5em; padding-bottom:1.5em; class=alert alertinfo>Press the Login button to authenticate via Database.com.</h3> <br/><br/> <a id=login class=btn btn-success>Login</a> </div> Formatting is applied through CSS styles, and the rendered output is shown below. Once the user taps the Login button, the OAuth login screen for Database.com gets displayed.

Figure 11. The user taps Login and the OAuth login screen for Database.com displays

All authentication is handled within the ChildBrowser, and is completely maintained by Database.com. As a developer, you dont have to worry about user account management or login functionality, as force. com handles this for you. The user simply must have permission to access your data objects (database) in Database.com. Once the user is successfully authenticated, the setupHomeView() function will be invoked, and will display the Home screen of the application. The setupHomeView() function resets/clears the contents of the container element, and then fills it with the contents of the templates.home template and adds the appropriate event handlers. function resetContainer() { //this removes child elements and cleans up event handlers container.children().remove(); container.removeClass(nopadding); } function setupHomeView() { resetContainer();

11/22

container.html( templates.home ); header.html( Welcome ); $(#addNew).tap(function (e) { setupFormView(); e.preventDefault(); e.stopPropagation(); return false; }); $(#queryMyRecords).tap(function (e) { setupListView(); e.preventDefault(); e.stopPropagation(); return false; });

You can view the templates.home template below: <h3>Please select an option:</h3> <a id=addNew class=btn btn-info>Add New Record</a> <br/> <a id=queryMyRecords class=btn btn-info>Query My Records</a> On a device, the user will see the rendered output as shown below. As you can see, there are two buttons, one for adding a new record, and another to query existing records from Database.com.

Figure 12. The rendered output

Next, lets examine what happens when the user clicks on the Add New Record button. When the user clicks this button, the setupFormView() button will be invoked, which creates a new form for gathering data from the user.
12/22

function setupFormView(data) { resetContainer();

var html = Mustache.to_html( templates.form, data ); container.html( html ); currentLead = data; //request current location if ( !(data && data.Id) ) { header.html( New Lead ); navigator.geolocation.getCurrentPosition(onGeoSuccess, onGeoError ); } else { header.html( Edit Lead ); } $(#save).tap( saveFormData ); $(#cancel).tap( navigateBackFromFormView );

The setupFormView() function will clear the container element, and fill it with HTML from the templates.form template. This is where you can see that templating become very useful. Next, lets examine the form template: <div id=form> <label for=first>First Name</label> <input id=first type=text value={{First__c}} /> <br/> <label for=last>Last Name</label> <input id=last type=text value={{Last__c}} /> <br/> <label for=phone>Telephone</label> <input id=phone type=text value={{Telephone__c}} /> <br/> <label for=email>Email</label> <input id=email type=text value={{Email__c}} /> <br/> <label for=notes>Notes</label> <textarea id=notes type=text>{{Notes__c}}</textarea> <br/> <span id=location class=alert alert-info>Location: {{Latitude__c}},{{ Longitude__c}}</span> <br/> <br/> <a id=save class=btn btn-success>Save</a> <a id=cancel class=btn btn-danger>Cancel</a> </div> The form contains the HTML that will be used to generate the user interface. Values wrapped in double brackets {{ and }} will be populated by data passed into the Mustache templating engine. Each value inside of the brackets corresponds to an attribute of a data object passed into Mustache.js.
13/22

The HTML string for the UI is generated using the Mustache.to_html() function. You can see in the setupFormView function above that the to_html() function uses a data parameter to generate the template HTML. When creating a new Lead, an empty object is passed into this function, so the forms HTML has blank values. When editing an existing lead, this exact function gets invoked, however a populated data object is passed in. This reuses the exact same HTML template, however populates it with the data that was passed in. When rendered within the PhoneGap application, youll see the form displayed as shown below. The GPS location is obtained through the PhoneGap API when capturing a new Lead.

Figure 13. The New Lead form displays the GPS location from the PhoneGap API

The user can enter appropriate data, and click either Save or Cancel. If the user cancels, the application will take the user back. However, if the user saves, this is where the application pushes data to Database.com. Inside of the saveFormData() JavaScript function, the data is retrieved from the input form, and assigned to a data object, which will be sent to Database.com. The saveFormData() function is used for both creating a new Lead, as well as updating and existing lead. If the currentLead variable exists, then the user is currently editing an existing Lead, otherwise the user is creating a new lead. If the user is creating a new Lead, the forcetk client.create function is invoked, otherwise, the client.update function is invoked. function saveFormData( event ) { var data = {}; data.First__c = $(#first).val(); data.Last__c = $(#last).val(); data.Telephone__c = $(#phone).val(); data.Email__c = $(#email).val(); data.Notes__c = $(#notes).val(); if ( currentLead ) { //copy it back to the object in memory currentLead.First__c = data.First__c; currentLead.Last__c = data.Last__c; currentLead.Telephone__c = data.Telephone__c; currentLead.Email__c = data.Email__c; currentLead.Notes__c = data.Notes__c;

14/22

);

} else if ( lastCoords ) { data.Latitude__c = lastCoords.latitude; data.Longitude__c = lastCoords.longitude; } try { if ( currentLead == undefined ) { sfw.client.create(Lead__C, data, saveDataSuccess, saveDataError

//use the original lat/lon location data.Latitude__c = currentLead.Latitude__c; data.Longitude__c = currentLead.Longitude__c;

} else { sfw.client.update(Lead__C, currentLead.Id, data, saveDataSuccess, saveDataError ); } } catch(e){ console.log(e); } } function saveDataSuccess( result ) { alert(Data Saved); navigateBackFromFormView(); } function saveDataError( request, status, error){ console.log( request.responseText ); alert( request.responseText ); } When calling client.create(), you just need to pass the type of object, the data object, and success and error callback functions. When referencing the type of object, you may have noticed that it is Lead__c, instead of Lead, as you may have expected. This is because custom objects and custom data fields in Database.com must use a __c suffix. When calling client.update(), you need to pass the type of object, the ID of the object being updated, the data object containing new values, and the success and error callback functions. If there is an error when saving data, a message will be displayed to the user. If there were no errors, the user will be taken back to the previous view. Next, lets examine the workflow for retrieving data from Database.com. From the application home screen click on the Query My Records button. This will invoke the setupListView() JavaScript function. function setupListView() { resetContainer(); var html = templates.list; container.html( html ); header.html( Leads ); if(lastData) { renderListData(); }

15/22

} The setupListView() function will clear the container, and populate it with HTML from the templates.list template. This template doesnt actually display the data, instead it sets up the dataContainer element where list data will be displayed. <div id=dataContainer>loading...</div> <br/><br/> <a id=cancel class=btn btn-danger style=width:70%>Cancel</a> If the user is navigating back from an edit form, data that is already in memory will be rendered. However, for a new request, the queryRecords() function will be invoked. Querying data from Database.com is very easy. When using the forcetk.js toolkit, you simply need to invoke the client.query() method, and pass in a SOQL query with success and error callback functions. SOQL is the Salesforce Object Query Language, with is very similar to SQL (Structured Query Language) used by other database offerings. SOQL enables you to create countless custom data queries from related objects, just as you may with SQL. Database.com also has an online Workbench tool that lets you test SOQL queries before putting them into your actual application. The queryRecords() function is below, where you can see it passing in the SOQL querty to retrieve data: function queryRecords() { var query = SELECT Email__c,First__c,Id,Last__c,Latitude__c,Longitude__c ,Notes__c,Telephone__c + FROM Lead__c + ORDER BY Last__c, First__c } sfw.client.query( query, onQuerySuccess, onQueryError );

else { queryRecords(); } $(#cancel).tap( setupHomeView );

function onQuerySuccess( response ) { lastData = { records: response.records }; renderListData();

function onQueryError( request, status, error ) { $(#dataContainer).html( Error loading data: <br/> + request. responseText ); } Once data is returned from Database.com, the onQuerySuccess function will be invoked, which invokes the renderListData() function. function renderListData() { if ( lastData ) { container.addClass(nopadding); var html = Mustache.to_html( templates.listItem, lastData ); $(#dataContainer).html( html ); $(#dataContainer).find(li).tap( onListItemTap ); $(#cancel).tap( navigateBackFromListView );

16/22

The renderListData() function uses the templates.listItem template to generate a HTML list based on the data the gets returned from the server, and adds a tap event handler to all <li> elements. Next, lets examine the contents of the templates.listItem template: <ul> {{#records}} <li id={{Id}}> <strong>{{Last__c}}, {{First__c}}</strong> <div class=subtext>{{Email__c}} </div> </li> {{/records}} </ul> This template instructs Mustache.js to loop over all records and will output a <li> element containing the Leads name and email address. Once the data is rendered, you may see the interface similar to the following screenshot. All list formatting is handled in CSS, so the visual presentation looks more like a mobile application list, instead of a bulleted HTML list.

Figure 14. CSS formatting presents list as a mobile application list

When the user taps on a list item, the onListItemTap function will be invoked. This function will obtain a reference to the JavaScript object corresponding to the list item that was tapped, and then will invoke the setupFormView() function discussed earlier in this article, passing in the appropriate object. function onListItemTap( event ) { var target = $( event.target ) while (target.get(0).nodeName.toUpperCase() != LI) { target=target.parent(); } var id = target.attr(id);
17/22

var data = getRecordById(id); setupFormView( data ); event.preventDefault(); event.stopPropagation(); function getRecordById( id ) { if ( !lastData ) return; var records = lastData.records; for (var x=0; x<records.length; x++ ) { if (records[x].Id == id ) { return records[x]; } }

Since it reuses the setupFormView() function, it will reuse the templates.form template, however populating it with the data retrieved from Database.com. See the screenshot below to see an example showing populated data.

Figure 15. templates.form is reused, populated with data retrieved from Database.com

Weve now covered an end-to-end solution for retrieving and persisting data in Database.com, so lets talk about deployment.

18/22

Deployment
One option for deployment is to export application archives from your IDE. For iOS applications you must use Xcode on OS X. For Android applications you must use Eclipse (can use Windows, Linux, or OS X), for BlackBerry applications you must BlackBerry tools, and for Windows Phone you must use Visual Studio (Windows only). Deploying to multiple platforms means having multiple development environments. Heres where PhoneGap Build comes in to assist! PhoneGap Build enables developers to either upload their code, or point PhoneGap build at a Git or SVN repository, and PhoneGap Build will perform a cloudbased compilation, providing the user with URLs to download device-specific application binaries. In a web browser, just navigate to http://build.phonegap.com, and log in. Once you are logged in, click on the new app button in the upper right hand corner. A dialog will be displayed that allows to upload your code or specify a Git or SVN repository.

Figure 16. In New app, upload your code or specify a Git or SVN repository

19/22

Once PhoneGap Build has access to your code, it will automatically perform a cloud-based compilation, providing you with links and QR codes to download your application binaries.

Figure 17. Cloud-based compilation, with links and QR codes to download your application binaries

If you use a QR code reader on a mobile device, you can download the application binary directly to that device just by snapping a picture. The QR code reader will start a download of the application binary files, which will be installed on your device. At this point, youll now have an application consuming data from Database.com, running on multiple devices, built on top of a single codebase. Pictured below is an image of this application running on both a Motorola Atrix (Android), and iPhone 4 (iOS).

20/22

Figure 18. The application running on both a Motorola Atrix (Android) and iPhone 4 (iOS)

The full source code for this application is available for download at https://github.com/triceam/Database.Com-PhoneGap-Sample. Feel free to use this as a starting point for your own PhoneGap and Database.com powered applications.

Why PhoneGap?
If youre still wondering whether or not PhoneGap is right for you, read on to see a few reasons you might want to use PhoneGap on your next project. Target multiple platforms PhoneGap enables you to leverage one codebase to target multiple mobile platforms. The Web already solved the problem of cross-platform applications with HTML, CSS, and JavaScript. PhoneGap leverages the ubiquity of HTML, CSS, and JavaScript to enable you to build mobile applications using these same technologies. Use Existing Skills Because PhoneGap applications are built using HTML, CSS, and JavaScript, developers dont need to learn new languages or development paradigms. Developers can quickly become productive developing mobile applications reusing skills and tools that they are already familiar with. This can save both time and money. Reuse Existing Tools Since PhoneGap applications leverage Web technologies, there are countless existing libraries or frameworks that you can leverage to accelerate application development. Whether it is a solution accelerator framework like jQuery or Zepto, a UI toolkit like Twitter Bootstrap, jQuery Mobile, or Sencha, or a data visualization library like Raphael.js, Highcharts, or RGraph.js, there are lots of resources both open source and commercially that you can leverage within your applications. Extensible PhoneGap offers some native operating system integration out of the box. However, if you want it to do more, it can. PhoneGaps native API is built on top of an extensible foundation that enables developers to create their own custom native code that can be invoked via JavaScript applications. This enables you to make PhoneGap do more if you so desire. Theres even a large collection of open source frameworks in existence on github at: https://github.com/phonegap/phonegap-plugins. If you want a plugin that will enable you to build multi-screen experiences for iOS applications connected to Apple TV/Airplay, all controlled by JavaScript, then theres a plugin for that:

21/22

Figure 19. Plugin for multi-screen experiences for iOS apps connected to Apple TV/Airplay

If you want to integrate a barcode scanner, analytics, push notifications, messaging and notifications, or advertising networks, there are plugins for those too (among many others). If you want to use a PhoneGap web view as a component inside of a native application, well, that is possible too. PhoneGap is a tool that enables and empowers developers to create applications that can be consumed in a variety of fashions, developed using familiar and extensible technologies. Open Source PhoneGap is completely free and open source. The full codebase for PhoneGap is freely accessible as a part of the Apache Cordova project. If you wish to add or change functionality, then you can do that. If you wish to build tools that build on top of PhoneGap, you can do that too. If you found a bug and want to fix it for everyone else that uses PhoneGap, then you have that ability (which is encouraged)!

Where to go from here


For more information on PhoneGap, go to PhoneGap Build. Learn more about the capabilities of Database.com through the Developer Center.

MORE INFORMATION

>

ABOUT THIS ARTICLE


Andy Trice is a Technical Evangelist for Adobe Systems. Andrew brings to the table more than a decade of experience designing, implementing, and delivering RIA for the web, desktop, and mobile devices. http://tricedesigns.com/ @andytrice

ONLINE RESOURCES PhoneGap official website http://phonegap.com/ PhoneGap Build http://build.phonegap.com/ Apache Cordova Project http://incubator.apache.org/cordova/

>

appliness

DONT WORRY, BE APPLI

Introducing Kendo UI Mobile


I recently discovered a neat framework I wanted to inform people of because it is another great option for developing in mobile.

This framework might especially appeal to Flex/AIR developers as well, so take a moment to read on. Its called Kendo UI Mobile, but this same company also has libraries for web and data visualization. In this article Im going to specifically focus on mobile, though the data visualization and web components play nicely with mobile as well according to the documentation and the things that I tried.

The framework is built on HTML5 and uses JavaScript/CSS to style the components to work cross-platform and automatically adapt to the look and feel of the native OS without the developer making any changes. It currently supports iOS, Android and Blackberry, and also has a theme for Windows Metro. It contains a set of CSS styles specifically for the different platforms so you can easily customize them to your liking by overriding the CSS class. The framework offers more than just UI components, it also has plumbing to do things like navigation between views, transitions, an extensive datasource and data binding implementation, drag-n-drop, validation, globalization support and more. I found their documentation and samples very well done and useful,

d n u o laygr

Difficulty
- rookie - intermediate - expert

- Kendo .js e n o b k c a B s .j t u o k c o n - K

Todo list

- modules - MVC

- mobile dev

by Holly Schinsky

and was impressed at how fast I was able to build things quickly and cleanly cross-platform. Coupled with PhoneGap, this could be a very powerful combination for mobile development. Before I go further, I do need to point out that this is not a free solution, there is a developer licensing fee of $199/yr for royalty free development using their mobile framework. You can review their whole pricing model here. I personally was impressed with it and would pay for it because I believe the time savings you could gain is well worth it. If youre coming from Adobe Flex/AIR I think you might find it especially easy to adapt to as well, I noticed many similar concepts. To use it you simply download their set of JavaScript and CSS files and include them in your application. Theres a kendo.mobile.min.js and .css file that includes everything (minified), but there are also specific files for different components if youre concerned about size and only need to utilize a certain feature. Also, every application needs to include a JavaScript kendoMobileApplication definition such as the following: ... window.kendoMobileApplication = new kendo.mobile.Application(document.body); ... When building your application, you can either depend on the jQuery-based calls for the Kendo components, or use the HTML5 data attributes as prescribed in their docs to achieve the same thing. So for instance you could define a back button in either way below: <a data-role=backbutton>Back</a> or var button = $(#button).kendoMobileBackButton(); Views are defined within an HTML file using the data-role=view attribute with an id. When you want to transition to one of these views, you simply use the hash sign # followed by the id of the view to transition to on an anchor tag. For instance, in the snippet below I define a view and an anchor tag that when clicked will transition to that view: <div id=about data-role=view data-title=About data-layout=app> <h2>This is the About View...</h2> </div> ... <a href=#about data-icon=about>About</a> I can also control the type of transition that will occur. The default is slide, but other transition options include zoom, fade and overlay. So for example, if I wanted to change the transition of my view above to a zoom, I could simply add the following data-transition attribute to the view: <div id=about data-role=view data-transition=zoom data-title=About datalayout=app> Note:If you exclude the hash sign, a remote ajax call will be assumed. You can also control the direction and duration of the transition. See the documentation for more details. Another thing I found particularly interesting with the Kendo framework, it that it includes a DataSource component you can use as an abstraction for local and remote (XML, JSON, JSONP) data. It supports CRUD (Create, Read, Update, Destroy) data operations and provides local and server-side support for Sorting, Paging, Filtering etc. and simplifies data binding and data operations in general. I created a simple application to try out the framework which used a DataSource for doing an ajax service call to search

2/8

the Yahoo Local Search APIs. My DataSource code definition is shown below: function getData(callback) { var template = kendo.template($(#customListViewTemplate).html()); var dataSource = new kendo.data.DataSource({ transport: { read: { url: http://local.yahooapis.com/LocalSearchService/V3/ localSearch?appid=YahooDemo&query=+search.value+&zip=+zip.value+&output= json&results=15, dataType: jsonp } }, schema: { data: ResultSet.Result }, error: function(e) { console.log(Error + e); }, change: function() { $(#resultListView).html(kendo.render(template, this.view())); } }); dataSource.sort = ({field: Distance, dir: asc}); dataSource.read(); $(#resultListView).kendoMobileListView({dataSource:dataSource,template: $(#customListViewTemplate).html()}); } The template Im referring to above that will be used for mapping the returned data looks like the following: <script type=text/x-kendo-template id=customListViewTemplate> <h4>${Title}</h4> <p>${Address}</p> <h4 id=distance>${Distance} miles</h4> <a data-role=button class=details-link>Visit Website</a> </script> For my sample Biz Finder app, I also wanted to create a header and footer for the mobile application. Whats nice with Kendo is that I was able to define a layout containing a header and footer globally to be used among multiple views. I just set up the layout with a data-id that is then referred to by the views I want to use it. So for instance, below is my global layout definition for my sample app: <!-- define multi-use layout for header/footer --> <div data-role=layout data-id=app> <header data-role=header> <div data-role=navbar> <span id=ttl data-role=view-title></span> <a data-align=right data-role=button data-icon=settings href=#settings></a> <a data-align=left data-role=backbutton href=#index>Back</ a>

3/8

</div> </header> <footer data-role=footer> <div data-role=tabstrip> <a href=#index data-icon=info>Info</a> <a href=#schedule data-icon=toprated>Schedule</a> </div> </footer> </div> And heres an example of one of the views I defined with the data-layout equal to the value of the dataid defined above: <div id=resultsView data-role=view data-title=Biz Finder datalayout=app> <input type=text maxlength=5 size=5/> <input type=search value=spa onchange=getData(onResult)/> <ul id=resultListView/> </div> Below is the result of my sample Biz Finder app running on the iPad:

4/8

and here is the same code running on the Galaxy tablet (Android OS):

Notice how the header and footer, buttons and entire look and feel are changed to adapt to the platform without any changes to the code. If you do want to control something for a specific platform, you can override or extend the CSS styles for them. For instance, I could define something like the following to control the paragraph element on each platform specifically: .km-ios p { color: #545454; font-size: 18px; } .km-android p { color: #FFFFFF; font-size: 16px; }

5/8

Note: There are a number of button icons included by default to mirror the native OS for things like search, settings, favorites etc. You can set a data-icon attribute on the HTML button tag to set a specific one. A list of those included can be found here. Below is a screenshot showing a sample of some included icons.

Theres also a Themebuilder offered by Kendo to be aware of, that allows you to choose styles and export a CSS file to be used with your application.

6/8

Other things worth noting Kendo supports the MVVM pattern (Model-View View-Model You can integrate Kendo UI with frameworks such as knockout.js or backbone.js. Theres an interesting project here that provides bindings for knockout.js and kendo.js. Each mobile view instantiates a scroller for its content. In addition you can specify data-role=scroller to add one to any element. The UI controls were designed with responsive design in mind allowing for a fluid experience across devices (automatically sized). Below are some screenshots showing some of the default mobile components for iOS to give an idea of whats included: ActionSheet Button Styles

Loading Popup TabBar Switch

7/8

Kendo UI for mobile can be used along with PhoneGap/Cordova easily. A summary of the steps are listed below (assumes Mac OSX), but see this post for a more specific walkthrough:

1. In XCode, create a Cordova-based project 2. Run the project to generate the needed www folder 3. Right click the root of the project and click Show in Finder 4. Copy the www folder that was just generated into your XCode project by dragging it in and selecting the Create folder references for any added folders option only (do not check the Copy items checkbox). 5. Copy the kendo js, css and jquery files from your kendo download into your project 6. Add references to the kendo js, css and jquery files in your index.html after the cordova include, such as: <script type=text/javascript charset=utf-8 src=cordova-1.7.0.js></ script> <script src=js/jquery.min.js></script> <script src=js/kendo.mobile.min.js></script> <link href=styles/kendo.mobile.all.min.css rel=stylesheet /> Note: In my example above I created the js and styles folders under my www folder and copied the files into those subfolders in step 5 accordingly. 7. Initialize a KendoMobileApplication object: <script> window.kendoMobileApplication = new kendo.mobile.Application(document. body); </script> 8. Thats it, youre ready to build your app and access the native device via cordova/phonegap APIs, or take advantage of the kendo framework elements! Related Links Device Simulator Quickly test out Kendo on different devices here Kendo UI Mobile Documentation

GET THE SOURCE CODE


Review and download the source code of this article on github: https://github.com/michaelchaize/appliness/blob/master/Kendo-ui-holly/index-kendo.html Discuss and exchange about this article with the Appliness community experts:

http://www.appliness.com/forums/topic/introducing-kendo-ui-mobile/

appliness

DONT WORRY, BE APPLI

MegaList jQuery Plugin

MegaList is a jQuery plugin that creates a touch-enabled list component, capable of very large datasets, complete with data virtualization.

A NEW LIST COMPONENT


Ive been working on lots of different projects lately. On several of them, Ive had the need for a reusable list component. In some cases, it needed to handle a large data set, in others it just needed to be selfcontained and easy to use. Out of these projects came MegaList: a reusable list component for jQuery, which Ive released as open source on Github. MegaList is a jQuery plugin that creates a touch-enabled list component, capable of very large datasets, complete with data virtualization. It was originally intended for touch-enabled devices, however it also works in many desktop browsers. For performance optimizations, the list component uses data virtualization techniques, so there are never more list elements in the HTML DOM than what is currently visible on the screen. As the user scrolls through content, the list updates the DOM elements accordingly. This makes scrolling lists of thousands of items extremely fluid. This works in a very similar way to ItemRenderer classes in Flex list and grid components. You can employ the list component using one of two approaches. One option is to declare the list structure in HTML markup, another option is to specify a dataProvider array, from which the list will create DOM elements.

ou Playgr

nd

Difficulty
- rookie - intermediate - expert

- jQuery - Virtual - DIV

Todo list
- scroll - optimize - wash fingers
by Andrew Trice

WHY?
Sometimes you need a pre-built list that you can reuse. Sometimes you need to scroll through big data sets, and other times you just need component logic kept away from your app logic. It doesnt fit every scenario, but it certainly fits a few. Data virtualization techniques allow you to quickly scroll through massive lists, without performance degradation. However, if your app really has 100K list items to scroll through, you should fire your UX designer.

SAMPLES
View the samples directory to see the scrollable list component in action. All samples are interactive, and scrollable via touch or mouse events, with function event handlers. Each of these examples can be scrolled using either the mouse or finger, and just tap/click on a row to select it, invoking the selection handler (alert message). On the desktop, you can also scroll with the scrollbar. Note: I originally intended this for mobile on the desktop, Ive only tested in Chrome and Safari. Simple List Created With Inline LI Elements This is a basic example with a list of 50 LI elements.

First create the HTML Structure, then instantiate the list via javascript, and add an event handler: Markup <div class=megalist id=myList > <ul> <li>item 0</li> <li>item 1</li> <li>item 2</li> <li>item 3</li> <li>item 4</li> <li>item 5</li> <li>item 6</li> <li>item 7</li> <li>item 8</li> <li>item 9</li> </ul> </div>

2/5

Script $(#myList).megalist() $(#myList).on(change, function(event){ var message = selected index: +event.selectedIndex+\n+ selected item: +event.srcElement.get()[0].outerHTML; alert( message ); })

Simple List Created With A DataProvider of 100,000 items: This is a more complex example using a massive data provider (100,000 elements!) with a label function.

First, declare the basic HTML container <div>, then create the list, then add a data provider array and optional label function. MARKUP <div class=megalist id=myList2 ></div> SCRIPT function listChangeHandler( event ) { var message = selected index: + event.selectedIndex + \n + selected item: + event.srcElement.get()[0].outerHTML alert( message ); } function createDataProvider() { var result = []; for ( var x=0; x<100000; x++ ) { result.push(x); } return result; }

3/5

function listItemLabelFunction( item ) { return Decimal: + item.toString() + , Hex: + item.toString(16); } $(#myList2).megalist() $(#myList2).megalist(setDataProvider, createDataProvider() ) $(#myList2).megalist(setLabelFunction, listItemLabelFunction ) $(#myList2).on(change, listChangeHandler) Styled Dynamic List Created With Remote Data: This is a dynamic example pulling data from twitter for a dataprovider, with a label function that returns HTML, instead of plain text strings.

MARKUP <div class=megalist id=tweets ></div> SCRIPT $(document).ready( function() { $(#tweets).megalist(); $(#tweets).megalist(setLabelFunction, listItemLabelFunction ); $(#tweets).on(change, listChangeHandler); $.getScript(http://search.twitter.com/search. json?q=andytrice&rpp=50&include_entities=true&result_type=mixed&callback=data Received ); }); function dataReceived( data ) { console.log(data); $(#tweets).megalist(setDataProvider, data.results ) } function listChangeHandler( event ) {
4/5

var message = selected index: + event.selectedIndex + \n + selected item: + event.srcElement.get()[0].outerHTML alert( message );

function listItemLabelFunction( item ) { return <div><img src= + item.profile_image_url + style=float:left;margin-right:10px;/><strong>@ + item.from_user + </ strong>: + item.text + </div>; }

Observations
Contrary to my expectations, using CSS3 translate3d is actually slower than using CSS top/left when placing the virtualized content. If you enable CSS3 translate3d and set backface visibility, there is an extremely noticeable performance degradation on both desktop and mobile devices. Ive experimented with lots of permutations to get the best performance possible. Im not finished yet, but Ive found that you can achieve significantly faster performance of DOM manipulation by removing elements from the DOM, manipulating them, then re-adding them. This is what is done within the updateLayout() method. The <ul> is removed from the DOM, <li> elements are added or removed, and then the <ul> is added back to the DOM. You may see a flicker on rare occasions, but I didnt find this overly intrusive. For small data sets, this may not be much advantage you can get better performance by just using something like iScroll in a <div> containing a <ul>. With large data sets, this is definitely faster. The more complex the HTML inside of your label function, the slower the animation will be.

get the source code

Review and download the source code of this article on github:

https://github.com/triceam/MegaList
Check the API here:

http://triceam.github.com/MegaList/
Discuss and exchange about this article with the Appliness community experts:

http://www.appliness.com/forums/topic/megalist-jquery-plugin/

appliness

TOOLING

Brackets: The Open Source Code Editor for the Web


Brackets is a new open source project founded by Adobe to push tooling on the web forward. Based on the principle that the best developers to build tools for web developers are in fact web developers, Brackets is built in JavaScript, HTML and CSS. MIT-licensed and hosted on github, Brackets is a project that challenges the status quo in not just how its built, but also with its innovative ideas.

WHY A NEW CODE EDITOR?


There are a lot of text editors out there, but not too many care exclusively about web developers. Brackets plays favorites and is optimized for the modern web. Its for designers who are as comfortable writing HTML and CSS as they are in Illustrator and Photoshop. Its also for JavaScript developers building complex apps targeting not only the browser, but everywhere the open web runs.

Because its built in JavaScript, HTML and CSS, if you use Brackets, you have the skills necessary to customize, extend and contribute to it. Easy to fork and with a flexible and open license, it truly is your editor. In fact, when you first open Brackets youll be looking right at the Brackets source code. On the team, we use Brackets to develop Brackets in this weird inception-style-yin-and-yang type of thing.

ou Playgr

nd

Difficulty
- rookie - intermediate - expert

- HTML t - JavaScrip - CSS

Todo list
- fix

- download - contribute

by Adam Lehman

Another incredible benefit to developing with open web standards is Brackets has the potential to run nearly everywhere. While were focused on the desktop first, we hope to supplement that version with a version of Brackets that can run exclusively in your browser. We also have a few ideas about how Brackets might be able to turn your tablet into your development environment. Brackets could also be embedded in your existing web applications. With a little help, all these versions could be developed in parallel. The possibilities are wide open.

INNOVATION
In addition to how its being built, Brackets has a few ideas that make it special: The Brackets team isnt down with floating panels, cluttered toolbars and other distractions. We want to keep it simple yet productive. We strongly believe it should just be you and your code and one of the way Brackets maintains its minimal design is through a new idea called Quick Edit. Every web project consists of several interrelated HTML, CSS and JavaScript files that are normally spread across the top of your editor in the form of tabs. In your common editors, its your job to keep a mind map of how all these files interrelate. If you want to apply or tweak a style on an HTML element, you have to located the right stylesheet; scroll around or quick search for the class; edit; save; then return back to your original file. In Brackets you simply open a Quick Edit by hitting Cmd/Ctrl + E. Brackets rips open your current document and displays only the CSS classes that apply to that element inline. Its something you have to see to believe. We can also apply the same ideas to JavaScript development. Smash the Quick Edit key on a function call and Brackets opens an inline editor with the JavaScript function body ready for edit. Instead of managing documents, developers can dive in and out of their code with ease. All this is included in the current build (Sprint 10). Of course, we arent just limited to using Quick Edit for coding functions. In the future, Quick Edit can also be used to display visual tools inline like a color picker, gradient designer or even just related documentation. Because Quick Edit isnt a floating panel, it never obscures your code which makes it moar

2/4

awesome. Want to try your hand at building an inline tool? There are already plenty of open source extensions to learn from. Brackets Quick Edit enables inline CSS and JavaScript editing :

THE WEB PLATFORM


Another core philosophy behind Brackets is that code should live in your editor but run in the browser. Today weve all gotten used to doing the save-reload-copy-paste dance. In a generic text editor, youre likely saving your code, switching to your favorite browser and hitting refresh. While your code is running you likely leverage in-browser tools to debug the application or tweak the design. You make several changes to get everything the way you want and then you have the epic chore of copying and pasting all those changes back to your editor. We call shenanigans. Brackets opens a live connection to your local browser and brings some of those in-browser tools back into the editor where it makes sense. When Live File Preview is enabled your browser shows real-time changes to CSS classes and properties as you type. Because the code lives in your editor but runs in your browser there is no need to save-reload-copy-paste. w00t! The current build of Brackets only supports Google Chrome for Live File Preview, but we hope to make this same connection to other browsers simultaneously with a little help from the browser makers. We prototyped support for the live editing of HTML and JavaScript and plan to include this ability in a future build. Just check out the public backlog to see what were working on next.

3/4

CONTRIBUTE
We need your help. There is a lot of work to do before Brackets is ready to be your favorite code editor. We want Brackets to be a truly open project, so we decided to develop Brackets in the open as soon as possible. So on May 1 we opened up our github repositories and started taking pull requests from the general community. We also posted our entire backlog of ideas and future features on Trello. If you look through our issues in github, you might notice a tag labeled starter bug. These are smaller issues that the team thinks will make a good introduction to working with and contributing to the Brackets codebase. If you are feeling a bit bolder and want to take on a larger task, you will find a starter feature label in our backlog. These are smaller features that are great for new Brackets developers who are still learning the code. We think that everyone can and should contribute to open source projects, so were lowering as many barriers as possible. Not all ideas makes sense to be added to the core codebase and for that reason, weve spent the past several sprints refining an extensibility API. Our growing community has already created several open source extensions ranging from inline MDN documentation (Pamela Fox) to JSHint and CSSLint integration (Ray Camden) to snippet support (John Rowny). We on the Brackets team are implementing several features like Quick Edit as extensions to keep the project modular. As I mentioned above, we really need your help to make Brackets awesome. We hope that ideas like Quick Edit and Live File Preview help plant a seed for new ideas of your own. We invite you to start hacking away, join our developer mailing list and hang out with us on IRC (#brackets on freenode).

GET THE source code

http://github.com/adobe/brackets

appliness

TOOLING

BRACKETS: Learning from the source

Brackets is a new open source code editor for web projects. ITS builT with HTML, CSS AND JAVASCRIPT. DISCOVER HOW TO USE IT AND HOW TO EXTAND IT.

An overview of brackets code architecture


An overview of Brackets code architecture Brackets, the new code editor for the web, is a fairly ambitious project on many levels, not the least of which is that the tool itself is written using javascript, CSS and HTML, with the developers using Brackets itself when possible. At a time when discussions around best practices for web app development have never been so lively, Brackets, which is open source, is a great opportunity for developers to witness how a com-

ou Playgr

nd

Difficulty
- rookie - intermediate - expert

- HTML t - JavaScrip - RequireJS

Todo list

- hack - write plugin - inspect

by David Deraedt

plex, real-life project can be built. While the code editor itself is still in its infancy (Sprint 10 just released at the time of this writing), there are already many things we can learn from studying its current source code. But first, a little disclaimer. While I do work for Adobe (which leads this initiative), I do not belong to the team responsible for Brackets, nor did I contribute to the source (though I did write a bunch of extensions). As a consequence, consider myself as an external observer, and as such my observations are subjective and some interpretations might even be plain wrong.

GENERAL ORGANIZATION
Brackets is hosted on GitHub, within two different repositories: one for the main source code responsible for the core web application; the other one containing the source of the native application shell, which makes it possible for the editor to run as a standalone application for Window and Mac OS (and before you ask: yes, Linux is on the roadmap).

The reason for this separation of concerns might be quite obvious: Brackets has the potential to be run in many places outside native desktop apps. This ubiquity is the main strength of web standards, and its what makes the project so exciting if you ask me.

Brackets uses the Chromium Embedded Framework for its native application shell. This framework embeds a version of Webkit and carries a payload of about 30 megs on each platform. Im often asked whether or not Cordova (aka Phonegap will one day be able to create desktop apps, and while we still dont have any roadmap for this, Im glad to see that Brackets has the potential to easily jump to another native shell technology, at least in theory.

In terms of file organization, the core Brackets repository has a pretty self-explanatory folder structure, and is rather well commented, so I think there is no need to detail each and every one of them sequentially here. Instead, Id rather highlight the various aspects that struck me as a developer.

Main code convention


A quick look at any JavaScript file in the repository will answer a common question regarding modern web apps. Yes, Brackets JavaScript code is written using modules. This should be no surprise. Modules are a great way to provide a clear, limited scope, and a proper encapsulation of your JavaScript code by taking advantage of javascript closures. Its also a great way to provide a basic level of privacy since only the members exposed via the returned object are publicly available. As you may know, that there are several format proposals for modules, but only two are really used today: CommonJS Modules, and AMD (for Asynchronous Module Definition). The Brackets team has chosen a hybrid approach: it uses the CommonJS format inside AMD-compatible wrappers. This was probably done to limit dependencies to either one of the formats.
2/7

define(function (require, exports, module) {

var otherModule = require(path/to/required/Module); var _privateStuff=Im private; var publicStuff=I need to be accessed from outside; function doStuff(){ console.log(publicStuff); } // Exposing public members through the exports object exports.doStuff=doStuff; exports.publicStuff= publicStuff; }); Note that the module parameter is not used: its only there for CommonJS compliance. Also, modules are loaded via the popular script / module loader RequireJS. For more informations on modules and module loaders, I highly recommend reading Addy Osmanis Writing Modular JavaScript. By the way, an important thing to keep in mind is that a module, and its corresponding file, may define zero, one, or many classes. So if youre looking for a class definition, dont necessary look for the corresponding file name.

Another interesting bit you might encounter while wandering around the repository is the use of deferred / promise mechanism. This pattern is used to handle asynchronous APIs which are needed if only because of the very nature of the relationship with the native shell. If youre not familiar with this API, Id recommend reading the related entry in the jQuery docs.

In case youre wondering, Brackets does not use any third party micro-architecture framework. Youll find some common concepts such as models, views and controller, but not formalized around a particular mechanism.

Finally, there is a page on the wiki describing code conventions used for Brackets. While nothing I saw should surprise any JavaScript developer, I still think its important for such an open project to agree and communicate about those practices, even if theyre quite common.

Code editing and document management


Much of what makes Brackets a tool for actually editing code comes from the use of a great third party project: CodeMirror. Everything regarding laying out a text document, to representing code and editing it in a proper way, comes from CodeMirror, including syntax highlighting and focus management. To be more accurate, Brackets uses a dedicated fork of CodeMirror2, but my understanding is CodeMirror committers have begun accepting pull request from the fork. Document and project management, however, is handled separately. This is the logic responsible for things like defining a project, a working set, selecting a file and keeping track of open files inside that project. While this may seem trivial when put this way, this is actually a very central part of any software designed to edit document.
3/7

Several classes are involved in this process, such as Document, Editor and their respective managers,

and understanding their relationship is essential to understanding the Brackets architecture. While a Document represents a file and its content, an Editor exposes methods to edit this document. Documents and Editors have a one-to-many relationship (one Document may be edited by several Editors). You can see the Document as a model, and the Editor as a middle-man between a view and the Document object it represents (some might call that a controller, even if thats not technically correct). The DocumentManager and the EditorManager classes create, delete, and give a central access for all documents and editors, respectively. For instance, to access the current document, you can ask the DocumentManager: var currentDoc = DocumentManager.getCurrentDocument(); But since Editors keep track of the document they edit, and the EditorManager manages all editors, you could also go this way: var currentDoc = EditorManager.getFocusedEditor().document; Note that the current Editor, and its corresponding Document do not necessary correspond to the currently opened tab in the UI, because Brackets has a notion of inline editors which can come on top of the main, full size editor representing the currently opened document. Editors give complete access to write the content and selection of a document, abstracting the CodeMirror implementation. The underlying code mirror API can still be accessed directly through _codeMirror, for example when you use _codeMirror.replaceSelection(newString);. You sometimes need to do that simply because the Editor API only covers a limited part of the CoreMirror features. In any case, if you want to get into Brackets, get prepared to spend some time in the CodeMirror API documentation. The Document API also exposes text editing operations, such as setText() or replaceRange(), which are delegated to its master editor (which itself delegates it to CodeMirror). So, to edit a Document, you can simply use its own API, regardless of editors. currentDoc.setText(Hello world); Selection management, however, is related to a corresponding view so its only available through the Editor object, using methods like getSelectedText() and setSelection(start, end). Heres how you could set the selection of the document which currently has focus: EditorManager.getFocusedEditor().setSelection({line:0, ch:0}, {line:0, ch:5}); Finally, a word of warning: As a workaround to circumvent the lack of weak references in JavaScript if, when you need to keep a reference of a Document object, you have to call Document.addRef(), and conversely, Document.releaseRef() when youre done). This includes all event listeners attached to documents.

Live development and inline Editors


One of things that make Brackets unique today is its so-called Live Development feature: Brackets is connected to the browser is such a way that modifications you do while you type are immediately shown in the browser. Needless to say, this is potentially a killer feature in terms of productivity. At the heart of the implementation of Live Development is the Inspector.js file, which is in charge of
4/7

the communication with Chromes remote debugger API using JSON over WebSockets. Other elements involved in this process include Agents - which keep track of changes and propagate them- and Documents which, again, represent CSS, JS and HTML files on the system. The Inline Editor feature, which makes it possible to overlay some content over code, is implemented through the InlineWidget class (the very basis of inline editors, which is just a panel floating over your code). The InlineTextEditor class is slightly more sophisticated: it inherits from InlineWidget and adds a simple text editor. The class youd use to create an inline editor such as Brackets default CSS inline editor, is the MultiRangeInlineEditor, which itself inherits from InlineTextEditor. To use such an Inline Editor, you have to register a provider function with the EditorManager, like this: EditorManager.registerInlineEditProvider(providerFunction); This function takes two parameters: the host editor, and a position object. Position objects are used by CodeMirror and contain two properties, the line number and the character position. Inside this function, youll simply instantiate your MultiRangeInlineEditor and pass it the corresponding Editor instance. function providerFunction(hostEditor, pos){ () var myInlineEditor = new MultiRangeInlineEditor(data); myInlineEditor.load(hostEditor); }

Views and user input management


I will not dive that much into styling, widgets, layout, and other UI details here, but I wanted to point out that, besides jQuery, Brackets makes use of the ber-popular Twitter Bootstrap framework for its elegant UI. As a consequence, it also uses the LESS CSS pre-processor.

Surprisingly, Brackets does not seem to use any templating system. Most of the UI is hard coded in the main brackets HTML file. My understanding is that this may change in the future.

More important to understand is how Brackets handles user inputs. To do so, it makes use of the Command pattern. This pattern describes how to encapsulate actions to be performed by the software (e.g. Open File) as objects (the Command). It is very convenient to map user gestures and inputs to those such objects, for many reasons. First, it allows the decoupling of user interactions from its consequence in the editor, which gives a much more maintainable code. Second, since actions are treated like objects, you can perform all sorts of operations on them. For instance, they can be pushed into an array. This is a popular pattern for implementing the basics of things such as history management and tool scripting, so you can expect those features in the future. Third, it makes the code much easier to maintain, and to test. In terms of implementation, registering a Command is a simple as that: CommandManager.register(menuName, commandID, callback);
5/7

It will then be triggered when the corresponding menu is selected, but you can also trigger it manually: CommandManager.execute(commandID);

Quality
Code quality is absolutely essential for any serious project, and of course Brackets is no exception. It uses JSLint to evaluate the quality of its code. JSLint is one of the most popular Javascript static analysis tool. It was made by Douglas Crockford as a way to easily scan your code and report any trouble, as described by its comment based configuration mechanism. Youll find JSLint configuration directives on top of every module: /*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ /*global define, $, FileError, brackets, window */ Note that JSLint is also used by default in the software itself for providing developers an immediate feedback on the quality of their code. But Brackets also uses a testing framework, Jasmine, to better guarantee the quality of the code. Jasmine is a popular Behavior Driven Development (a flavor of Test Driven Development) framework used for JavaScript development. A test runner has been included in the editor itself, so that it can easily be tested... from itself.

Early Extensibility Model


An early extensibility mechanism is already included, allowing us to easily extend Brackets functionalities without having to become an official contributor. The typical workflow for doing so would be to launch a second instance of Brackets for testing the actual code, using the Debug > Experimental > New Window command. The extension itself is of course described as a module, but in a somewhat separate scope from the rest of the source code. To load dependencies from Brackets, you have to use bracket.getModules(). Heres a complete Hello World extension originally written by Mike Chambers. /*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */ /*global define, $, brackets, window */ /** Simple extension that adds a File > Hello World menu item */ define(function (require, exports, module) { use strict;
6/7

var CommandManager = brackets.getModule(command/CommandManager), Menus = brackets.getModule(command/Menus); // Function to run when the menu item is clicked function handleHelloWorld() { window.alert(Hello, world!); } // First, register a command, a UI-less object associating id to handler var MY_COMMAND_ID = helloworld.sayhello; CommandManager.register(Hello World, MY_COMMAND_ID, handleHelloWorld); // Then create a menu item bound to the command // The label of the menu item is the name we gave the command (see above) var menu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU); menu.addMenuItem(MY_COMMAND_ID); // We could also add a key binding at the same time: //menu.addMenuItem(MY_COMMAND_ID, Ctrl-Alt-H); // (Note: Ctrl is automatically mapped to Cmd on Mac) // Or you can add a key binding without having to create a menu item: //KeyBindingManager.addBinding(MY_COMMAND_ID, Ctrl-Alt-H); // For dynamic menu item labels,you can change the command name any time: //CommandManager.get(MY_COMMAND_ID).setName(Goodbye!);

});/

Whats great is that your extension can take advantage of the pretty much all of Brackets features, like InlineEditor mechanism. Thats pretty much what I wanted to tell you about Brackets for now, folks. I hope that this somewhat high level overview will make you want to know more about this exciting project, and hopefully help you get into Brackets quicker. For a better, deeper understanding of how Brackets works, I recommend taking a look at its wiki and the various videos on youtube shot at the first Brackets hackathon.

E E IV W S E U I L RV C X TE IN

ERIC MEYER
THE CSS EXPERT
1/8

CSS AND THE MODERN WEB

WE ARE VERY PROUD TO INTERVIEw ERIC MEYER who has been working with the Web since late 1993 and is an internationally recognized expert on the subjects of HTML and CSS.

Hi Eric, thank you for taking your time to interview for Appliness. Its a great honor to have you as our feature interviewee. Can you tell our readers a bit about yourself?
Im honored that you asked me to be here! I got my start with computers somewhere around 1978 and on the web in late 1993, and Ive been lucky enough to both observe and participate in the ebbs and flows of the webs evolution. When I started out, we didnt even have table markupfor that matter, inline images were a hot new thing. In the years since, Ive written a number of books and articles about CSS, become known as a standards guy, appeared on many a conference stage, and co-founded both the Microformats movement (with Tantek elik and Matt Mullenweg) and the web design conference series An Event Apart (with Jeffrey Zeldman). Im a hair over six feet tall, live in a 1920 center-hall Colonial in Cleveland Heights, Ohio with my wife and three children, and am in all likelihood a supertaster.

You manage to stay pretty busy writing books, speaking around the world, co-founding projects and events. Are there any projects you hope to have more time for in the near future?
Id really like to make a start at preserving the history of the web and its technologies. For example, why do we embed images with an IMG tag instead of, say, an EMBED or OBJECT element? Theres a known answerbecause thats what Marc Andreesen decided but how many other such answers are still unknown? We know that blockquotes have a 40-pixel indent because thats what Mosaic did, but why did Mosaic do that? Why did we end up with CSS instead of JSSS or DSSSL? What compelled the creation of Flash? How did HTML4 get organized, and what effects did its inclusions and exclusions create? And so on. These things are important because we tend to take whats in front of us for granted, but if we understand how we got to where we are, we can better see how to move forward. So Im working to preserve artifactsmostly web pagesas well as start talking with old hands about their experiences and perspectives on the web. The current plan is to conduct audio interviews that will be released in various forms, though I dont have all the details quite nailed down. Hopefully there will be news soon! Beyond that, I hope to compile that research and the work of others into a semi-centralized communitydriven site, something along the lines of folklore.org, and possibly to write a book chronicling the emergence and evolution of the web.

Clearly, youre a history buff. Do you have any broad thoughts on the Internet and its place in history?
Enough of a buff that I have a B.A. in History, in fact! The Internet is clearly one of a number of broadly disruptive advances, like printing or the telegraph or mass production. We tend to think of it as profoundly changing everything in the whole world, which is overstating things a bit. The telegraph was far more disruptive to civilization, for example, as Tom Standage brilliantly demonstrates in The Victorian Interneta book thats a model for my own research into web history, in fact, along with James Burkes The Day the Universe Changed. The Internet isnt

2/8

quite as world-changing as was the telegraph, or perhaps we should say it isnt quite as world-changing yet. Its always hard to assess major shifts when theyre underway. They may move much further than they appear at first glance.

You have seen CSS in its very early stages, even before Internet Explorer 3 shipped. What solution did it provide for what you were looking for at the time that HTML or other technologies couldnt?
At the time, Id been resisting table-and-spacer-GIF design because it just seemed so icky and wrong. The visual results you could get were compelling, but the means seemed to me much too awful to justify the ends. CSS promised to get us those visual ends through much better means. Just the ability to say make all elements of this type look like this was a radical change. The ability to change element separation distance without extra <br> elements, to set font sizes to anything the browser could compute instead of being stuck with seven discrete steps, to change the type of box an element generatedall were far beyond what HTML could do. It took us years to even come close to discovering everything you could do with just whats in CSS1, never mind all that came after it. Of course, theory and practice are always much closer in theory than they are in practice. There were many years and browser revisions to slog through before we could start using CSS as it was truly meant to be used. Were pretty well there now, in fact. CSS does continue to advance and so we continue to see inconsistencies in browsers, but thats always going to be the case. The only way to avoid inconsistency between browsers is to have only one browser. Some would argue thats exactly what should happen, but I disagree completely. Monocultures are always more fragile and less responsive than ecosystems. Every time someone asserts that all browsers should just run WebKit, I wonder how theyd respond to the idea that all browsers should just run Trident, the engine in Internet Explorer. There were calls for that approach, a decade back. I think were all better off for their having been ignored.

CSS is heading in a lot of different directions all at once, which isnt actually a bad thing!

Where is CSS heading? What is it missing?


Its heading in a lot of different directions all at once, which isnt actually a bad thing! Its really great to see it progressing on multiple fronts. What its missing is the same thing its been missing since its inception: a really strong, flexible layout system. Floats and positioning were never enough, and in fact floats were never designed to be layout tools in the first place. Thats been a gaping hole in CSS from the outset. However, there are strong pushes in that direction right now, and it could be that in a year or two we can consider that hole filled. It will depend on how browsers implementation schedules go. Of course, anyone who wants to try out Grid Layout can do so right now in Internet Explorer 10. For the rest, youll have to wait. I just hope not for longits been far too long already! JS-based polyfills can help bridge that waiting period, but we really need native support across the board. Ive despaired of it ever happening for about a decade now, as various advanced layout systems were proposed and then ignored, but Im starting to feel optimism about Grid Layout. It might finally be time.

How can the general public help with inconsistent CSS support? How much are these inconsistencies related to browsers just not wanting to place nicely together?
3/8

Generally speaking, find the problems and blog about them with clear test cases. Reporting bugs to browser teams via their bug-reporting channels is always a good idea; both Mozilla and WebKit have

open bug databases where anyone can search open bugs and submit their own. These days, theres very little of implementers using inconsistencies to wage war, as sometimes happened in the late 1990s. Some have made the case that WebKits tendency to add new CSS-like features and then never submit them for standardization is a major problem, and I tend to agreethough it could bite them if someone else standardizes something WebKit hasnt documented and the standard disagrees with WebKit. Where browsers do implement the same thing, like gradients or drop shadows, they tend to work pretty hard to be consistent even in the edgiest of edge cases. The day I saw several implementers working to figure out what to do when a boxs drop shadow has a blur value of several hundred pixels, I knew we were in a whole new and much better era.

Are the CSS Working Group and browser representatives doing enough to encourage support for web standards?
Well, one could always ask for more, but I think theyve done pretty well. Its hard to expect them to add new cool stuff at the frantic rate we desire and also take the time to write extensive tutorials and give talks at every conference and classroom. Of late, the failing of browser representatives has been in encouraging developers to use browser-specific syntax for features that are supported across multiple browsers. Every time a cool experiments site gets launched with one-browser-only vendor prefixes, we take a step backward. Of course, every site that breaks in any browser but one is a call to return to 1997, and weve been seeing plenty of those lately, at least in the mobile space. Its why browsers are thinking of recognizing each others vendor prefixes.

An Event Apart Seattle 2009 (by AxsDeny)

You mention the implementation of color is more complicated in CSS3 than it seems at first glance. How much of a need was there to create additional color value options to RGB? Do HSL and HSLa fill a big gap?
Did I say that? Oh dear. Hopefully what I meant was that there are a lot more options nowalpha channels as well as HSL values. I think HSL did fill a gap in CSS, which was all about RGB values. That always felt like a holdover from the beginning of HTML-based colors, which were all in hexadecimal triplets. Transferring those over and then having two rgb() patterns was a good first step, but it always seemed like there should be more. HSL is great for designers who arent used to thinking in RGB terms, and its a more immediately intuitive system. Once you internalize the hue wheel and the effects of varying saturation and lightness, its a very straightforward system. Id like to see even more color systems supported, like HSB and CIELAB. Let a thousand colorful flowers bloom!

Youve been doing a lot of work on gradients lately. Is everything changing? Should designers be excited? Concerned?
The syntax is changing, yes, but not in major ways. I think its time to be excited. Gradients are likely to become unprefixed soon, which means the syntax is consistent across implementations. The behaviors seem to be consistent as well, though theres always room for bugs. I expect that within six months to a year well be using gradients with confidence. Now its just up to us to use them with taste and decorum.

4/8

Do you recommend using CSS Frameworks? Under certain circumstances?


Sure, if it makes sense for your situation. Not everyone will benefit from a framework, but for those who do, theyre fantastic. My own tendency is to not use frameworks for the same reason I tend to avoid JS libraries: I end up loading the whole package and only using a tiny slice of whats on tap. That means everything else is deadweight. The slice I use and remaining deadweight varies from one circumstance to another, but the basic principle doesnt change. However, thats me. I operate in a much different environment than, say, a web app developer or a corporate-presence designer or a portal developer. Those are situations where CSS frameworks make a lot more sense. And of course frameworks are fantastic during development, when you just want to get ideas up and running, and test variations quickly. Sometimes once youve done all that, it makes sense to carry the framework forward into production. Other times, it doesnt. The tricky part is knowing which is which, and I dont think theres a formal way to describe that process. So much of what we do on the web is an art, where you have to balance competing priorities and decide which path works best for the situation at hand, and this is no exception.

What are your thoughts on CSS languages and/or extensions such as Less and Sass?
Im a big fan of extensions like Less and Sass, because they help point the way for native CSS. They provide real-world use cases. As an example, CSS variables were one of those things that had been proposed and rejected for years upon years. Less and Sass made variables really easy, and so lots of people used them. That made it much easier to go to the Working Group and say, Look, authors are doing this. They clearly want it. Lets make it part of the language. Thats a much stronger case than, Hey, I bet authors would use these if we did it. I expect there to be similar effects in color, where the ability to lighten or darken a color by a specified amount is already easy in CSS extensions, so theres desire to make it similarly easy in native CSS.

What benefits has CSS has provided in moving away from table-based design? How has this opened the world of possibilities for designers and developers? What other benefits or drawbacks came as a result?
The biggest benefit has been in letting us drop table markup for layout in about 99.44% of cases, and even in those cases where table markup or table-role display values are used, letting us drop all the spacer GIFs and background-color decoration cells. My biggest objection to table-based design was always its gross inefficiency and cruftiness; the semantic clash was always secondary to me. Granted, table layout was all we had from 1994 through 1998 or so, but it was always an awkward, ugly transition phase and its one Im glad to see over. Well, except in those 0.56% of cases where the design needs are such that tables are really the only practical answerand even those Im hoping to see eradicated by Grid Layout in the next year or two.

You have written many books on CSS and web standards, are a past member of the CSS Working Group and promote CSS around the world but, tell us truly, when should CSS be used for evilor should it?
When its funny.

What is the aim and intended purpose of the Global Multimedia Protocols Group? Has it been widely adopted?
5/8

There are several answers to that first question. One is that its a fun invocation of a geek in-joke. Another is that its a serious attempt to add meta-information to the web without falling into the usual pits semantic technologies usually fall into. But more fundamentally, its a group of like-minded friends who had the same basic ideas: that it should be easy for authors to express semantic concepts about their information; that it should be easy to extend those semantics; that decentralized evolution is the best way to enrich a vocabulary; and that all of this should be done within the framework of existing technologies and languages. This led to a statement of basic principles you can find at http://gmpg.org/principles, which in re-reading now, Im struck by how closely I still hew to them. The friends in this case were me, Tantek elik, and Matt Mullenweg. We started out with the XHTML Friends Network (XFN), which specified a very simple way to indicate personal relationships in markup. That launched the Microformats community, which has led to all kinds of semantic enrichment. I dont even know how many millions or billions of pieces of microformatted data inhabits the web now, but its, well, its a lot. Anyone who remembers the Creative Commons search, for example, or the automatic event harvesting of early Upcoming.org, benefitted from Microformats. And those are just two of many, many examplesso many Ive forgotten most of them. So while GMPG itself couldnt really be widely adopted, Microformats certainly were. Furthermore, you can see their influence on later efforts in the same general area. Not enough of an influence from a principles point of view, Im sorry to say, but a lot of the conceptual DNA is still there.

You co-founded the very successful conference series An Event Apart? What benefit does this conference fill for people who make websites what makes it unique?
There are a lot of things that make it unique, but the most important thing is the speakers we invite as well as the curation of topics and how they fit together. That might sound like two different things, but it really isnt. We strive to speak to both the design and development sides of the web, and to challenge our audience to see what they do and how they do it in new ways. Sometimes that means bringing in new concepts, as with content strategy; or by having a speaker who challenges established concepts, like how best to write CSS or the actual usefulness of widely-used UI elements. Either way, we want the audiencewhich is generally comprised of very smart, very experienced web handsto come away with a ton to think about, maybe even to argue against, and, like I say, a new way of seeing their own work. Thats not exactly easy, but were dedicated to making it happen in every show, and I like to think weve been successful.

In your opinion, what feature(s) in HTML5 has been the most useful?
I really, really like the document outlining mechanism. It solves a lot of semi-arcane problems like ordering-of-heading snafus in situations where, say, a CMS is pulling together a bunch of pieces of content. Even better, it provides much stronger support for accessibility tools, some of which are already working on outlining support. In the past, HTML outlining was a guessing game, accessibility-wise. HTML5 can make that a solved problem. Im also a fan of all the new input types and what they potentially deliver to document authors. Being able to mark inputs as accepting an email address or telephone number or a date-time value let UAs decide what kind of input to offer. If youve filled out a form on a recent mobile device and had the keyboard change based on the input field, youve benefitted from HTML5. Theres also the promise of UAs doing some basic input validation before passing it on to the server, like checking to see that a phone number has only numbers in it. You still have to do the back-end checking to make sure

6/8

the input isnt garbage, but if a browser can tell the user, Hey, you tried to put a letter into a telephone number, thats great for the user because they can correct it without sitting through a roundtrip to the server, and its great for the developer because thats one less server request to process just to return the whole form with an error flag.

Eric Meyer by http://www.flickr.com/photos/localcelebrity/

How would you best recommend testing CSS? Are there any particular tools youd recommend?
Validate, validate, validate. Once youre sure you havent misspelled h1 or accidentally dropped a semicolon, then you can start worrying about what a browser is actually doing. Beyond that, Im a big fan of both Firebug and the Web Developer Toolbar as a powerful one-two combo, but really any built-in web inspector is great. Ive heard some strong recommendations for Chromes DevTools, for example. Just keep in mind that, in general, web inspectors can only report what the browser tells them, and browsers lie.

What do you mean, browsers lie?


A basic example is that visited links are treated as identical to unvisited links for privacy reasons. There are only a few CSS properties you can apply to visited links, all color-based, and both the browsers DOM as well as inspectors will tell you their colors are the same as if they were unvisited. Its a direct, baldfaced lie, and its done by design. A slightly more subtle example is what happens if you set an element to have a font-size of, say, 10.66px. Some web inspectors will tell you the elements font size is 10 pixels and some 11 pixels, even though the internally-held value is 10.66 pixels, or more likely something equivalent to that precise measure. Youre basically at the mercy of whatever the DOM has been told to do in those situations, and every browser has its own policy.
7/8

How has the wide implementation of web technologies in non-standard websites and devices complicated the implementation of CSS?
I think its mostly complicated the way people think of CSS, not the language itself. Its easy to think about a language in only one or two contexts, like desktop and tablet. But then you add televisions and handhelds and wall displays and dashboard speech modules on and on and on and you start to wonder if one language can handle everything. The modularization of CSS certainly helps, because you can add another module for, say, wall displays that describes how to adapt CSS to that environment and maybe some new properties and values.

Do you feel as though we are in a pivotal time of change for advances in web standards and technologies?
I really do. Theres been much, much more activity on the part of the CSS Working Group and other core WGs in the past few years, and browsers have really been pushing the state of the art forward. I dont see that changing any time soon. In fact, I would only expect it to change if browser makers abandon basic web technologies like CSS and HTML for some successor medium, or else if one or two of the dominant browsers exit the field entirely, like IE did for a few years there in the early 2000s. There are also some great tools emerging to help manage things like layout, gradient patterns, vendor prefixing, and animation. Those will also drive changes forward as more and more authors experiment and find the edges of whats possible, thus making it clear where the next advances need to happen.

We learn more when we learn together.

Can you give us any parting words or well wishes for the technological future?
If I could only pass on one thought, it would be: Dedicate yourself to your craft. Web design and development isnt a field that lends itself to pat answers; we can still to this day have a rousing debate about the best way to mark up a list of names and telephone numbers, let alone layout strategies on mobile versus desktop. We have so many tools at our disposal, but its up to us to figure out the best way to use them. What works in one situation may be a terrible idea in another. Sometimes you discover that the best approach is exactly the opposite of what youre used to doing. New approaches and tools come into play all the time. You have to be dedicated to the idea that what you are doing is a craft, and every time you start a new project, you are relearning what you know and how to best use your knowledge. And, even more importantly, share what you learn with colleagues as well as with those just starting out. We learn more when we learn together.

8/8

appliness

FOCUS ON CSS

Css filters

CSS filter support recently landed within WebKit nightlies. CSS filters provide a method for modifying the rendering of a basic DOM element, image, or video. CSS FILTERS SHOULD BE SUPPORTED in IOS6.

CSS filters allow for blurring, warping, and modifying the color intensity of elements. Lets have a look at how CSS filters work and how you can quickly create elements that are beautifully filtered!

There are many CSS filters to choose from: grayscale, blur, sepia, saturate, opacity, brightness, contrast, hue-rotate, and invert. While each property value generally falls between 0 and 1, there are a few exceptions. The blur property uses a unit of pixels and can be any whole number, and the hue-rotate filter value is a whole number with a deg unit. The following CSS snippet will blur an element: copy.myElement { -webkit-filter: blur(2px); } Multiple filters are separated by spaces, so we could also add grayscale and opacity values to the blur: copy.myElement { -webkit-filter: blur(2px) grayscale (.5) opacity(0.8); }

Lets get crazy with hue-rotate as well: copy.myElement { -webkit-filter: blur(2px) grayscale (.5) opacity(0.8) hue-rotate(120deg); } If static filtering isnt enough for you, CSS filters also animate with @-webkit-keyframes: copy@-webkit-keyframes testAnim { 0% { -webkit-filter: grayscale(0.5) blur(1px) saturate(2); } 100% { -webkit-filter: grayscale(0.2) blur(6px) saturate(9); } } /* the photo to be animated via filters */ #animatePhoto {} #animatePhoto:hover { -webkit-animation-name: testAnim; -webkit-animation-duration: 2s; -webkit-animation-iteration-count: 1; -webkit-animation-direction: alternate; -webkit-animation-timing-function: ease-out; -webkit-animation-fill-mode: forwards; -webkit-animation-delay: 0s; } Expect a performance hit with heavy CSS filter usage; be sure to heavily test your site wherever filtering is used. CSS filters have not yet hit mobile, but assume that CSS filters will be taxing in that environment as well. Note: Ive yet to successfully filter a <video> tag; its possible that feature isnt in the first implementation. < WARNING - CSS filters should be available with iOS6, not before. You can test it on your desktop. The additional of CSS filters to the web provides a new level of customization for images, video, and DOM nodes in general. We should see some solid, practical uses for CSS filters emerge in the coming years. Have fun playing around with CSS filters and let me know if you can think of some immediate, practical uses!

ABOUT THIS ARTICLE


David Walsh is a 28 year old Front-End Developer in Madison, Wisconsin. He is a Web Developer for Mozilla, the ever-innovating open source organization that brought you Firefox, Thunderbird, and . He is Founder and Lead Developer for Wynq Web Labs, core developer for the MooTools JavaScript Framework and Co-Founder of Script & Style.

ONLINE RESOURCES Wynq Web Labs http://davidwalsh.name/wynq


MooTools JavaScript Framework http://mootools.net/ticles/css-shaders.html Mozilla Firefox http://www.mozilla.org/en-US/firefox/new/

http://davidwalsh.name/ @davidwalshblog

appliness

FOCUS ON CSS

understanding Css filter effects

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
Filters are a powerful tool that web authors can use to achieve interesting visual effects. In this article well cover the history of filter effects, what they do and how to use them. Well cover examples of all the predefined filters defined for CSS with some examples. Well also cover performance considerations for using them on desktop and mobile devices since knowing the speed impact of filters is important for a good user experience. Finally well review the current state of implementation in modern browsers.

THE PAST, PRESENT AND FUTURE OF FILTER EFFECTS


Filter effects originated as part of the Scalable Vector Graphics (SVG) specification. They were created to apply a number of different pixel based image effects to a vector drawing. Over time as browser vendors added SVG capabilities into their browsers, the usefulness of filters became evident. Robert OCallahan from Mozilla came up with the brilliant idea of using SVG filters through the application of CSS to normal HTML content. Robert prototyped an early version that showed how powerful the combination of filters and CSS styling could be. The CSS and SVG working groups in the W3C decided to harmonize the use of filters for both HTML and SVG via CSS styling, and thus the filter property for CSS was born. Right now a joint task force of people working on CSS and SVG is doing a ton of work to make filters universally useful. You can find the current specification for all this stuff here.

A NEW LIFE FOR THE FILTER CSS PROPERTY


Deja Vu sometimes strikes a web developer when seeing filter in CSS styles. This is due to the fact that old versions of Internet Explorer had a filter property exposed via CSS to perform some platform specific functionality. This has been deprecated in favor of the standard filter property which is now part of CSS3. So when you see filter out in the wild on some old web pages, theres no need to be confused. The new filter property is where all the action is, and new versions of IE are implementing it just the same as all modern browsers.

HOW FILTERS WORK


So what does a filter do exactly? The easiest way to think of a filter is as a post processing step that does something magical after all your page content has been laid out and drawn. When a browser loads a web page it needs to apply styles, perform layout and then render the page so theres something to look at. Filters kick in after all those steps and just before the page is copied to the screen. What they do is take a snapshot of the rendered page as a bitmap image, then perform some graphics magic on the pixels in the snapshot and then draw the result over the top of the original page image. One way to think of them is like a filter placed on the front of a camera lens. What youre seeing through the lens is the outside world modified by the effect of the filter. This of course means that theres time consumed when drawing a page with filters on it, but using them properly will have minimal impact on the speed of your site. Also, just as you can stack a number of filters in front of each other on your camera lens, you can apply an arbitrary number of filters one after the other to achieve all sorts of effects.

FILTERS DEFINED USING SVG AND CSS


Since filters originally came from SVG there are different ways to define and use them. SVG itself has a element that wraps up definitions of various filter effects using XML syntax. The set of filters defined by CSS take advantage of the same graphics model, but they are much simpler definitions that are easy to use in a style sheet. Most of the CSS filters can be expressed in terms of SVG filters, and CSS also allows you to reference a filter specified in SVG if you want. The CSS filter designers have taken great pains to make the application of a filter easier for web authors, and so this article will just cover the filters available directly from CSS, ignoring the SVG definitions for the time being.

2/11

HOW TO APPLY A CSS FILTER


Note: The description and examples below use the official W3C syntax that will be available in all modern browsers eventually. To use filters now, you need to use the vendor prefixed version of the filter property. But dont worry theres an easy way to handle that at the end of this article. Using filters from CSS is done by using the filter property applied to any visible element on your web page. For a very simple example you could write something like div { +filter: grayscale(100%); }

and that would make the content inside all <div> elements on the page turn gray. Great for making your page look like a TV image from the 1940s.

Original Image

Grayscale Filtered Image

Most filters take some form of parameter to control how much filtering is done. So for example if you wanted to style your content to be half way between the original color and a grayscale version youd do it like this: div { +filter: grayscale(50%); }

Original image above but 50% gray filtered

If you want to apply a number of different filters one after another, its easy - just place them in order in your CSS like so: div { +filter: grayscale(100%) sepia(100%); }

3/11

That example will first make all the original color grayscale and then apply a sepia effect, and would end up looking like:

With the flexibility available for applying filters one after the other, all sorts of effects can be achieved its totally up to your imagination to experiment with creating amazing results.

WHAT FILTERS EFFECTS ARE AVAILABLE USING CSS


So the original SVG filter mechanism is both powerful but at the same time can be daunting to use. Because of that, CSS introduces a bunch of standard filter effects that make using them really easy. Lets take a look at each of them and see what they do. grayscale(amount) This converts color in our input image to a shade of gray. The amount applied controls how much gray conversion is applied. If its 100% then everything will be a shade of gray, if its 0% the colors are unchanged. You can use a floating point number here if you prefer it over percentages, i.e. 0 works the same as 0% whilst 1.0 works the same as 100%.

Original

grayscale(100%)

4/11

sepia(amount) This gives the colors passed in a sepia tinge like in old photographs. The amount applied works in the same way as for the grayscale filter - namely 100% makes all the colors completely sepia toned and smaller values allow the effect to be applied in smaller proportions.

Original

sepia(100%)

saturate(amount) This applies a color saturation effect to the colors which makes them look more vivid. Its a cool effect that can make photos look like posters or cartoons.This effect also allows you to use a value greater than 100% to really emphasize the saturation. Definitely an effect that can make things look pretty funky!

Original saturate(10)

Note: In Chrome version 19, the saturate() function takes an integer (without the percentage sign) instead of the decimal or percentage, as per the W3C spec. Not to worry, this known bug will be fixed.

5/11

hue-rotate(angle) This one is a bit of a color geek effect that can be used for interesting results. What it does is shift the colors around to make an input image look completely different. If you can imagine a color spectrum going from red to violet around a color wheel, then this effect takes the original color on the wheel as input and rotates it by the angle parameter to produce the color on the wheel to which it rotated as the output color value. So all the colors in the image are shifted by the same angle on the wheel. This is of course a simplification of what it does, but hopefully close enough that it makes sense.

Original hue-rotate(90deg)

invert(amount) This effect flips the colors - so that if the amount applied is 100% the output looks like a photo negative back from the old film days of cameras! Just like before, using values smaller than 100% will progressively apply the invert effect.

Original invert(100%)

6/11

opacity(amount) If you want the content being filtered to look semi-transparent, this is the one for you. The amount value defines how opaque the output will be. So a value of 100% is completely opaque so the output will be exactly the same as the input. As the value drops below 100% the output image will become less opaque (more transparent) and youll see less and less of it. This of course means if it overlaps something else on the page, the stuff underneath will start to become visible. An amount of 0% means it will completely disappear - but note, you can still get events like mouse clicks etc. to happen on completely transparent objects so this is handy if you want to create clickable areas without displaying anything. This works the same as the opacity property you already know. In general the CSS opacity property isnt hardware accelerated, but some browsers that implement filters using hardware acceleration will accelerate the filter version of opacity for much better performance.

Original opacity(50%)

brightness(amount) This is just like the brightness control on your TV. It adjusts the colors between completely black and the original color in proportion to the amount parameter. If you set this one to 0% youll see nothing but black, but as the value goes up towards 100% you see more and more of the original image brightening up, until you hit 100% where its the same as the input image. Of course you can just keep going - so setting something like 200% will make the image twice as bright as the original - great for adjusting those low light shots!

7/11

Original brightness(140%)

contrast(amount) More controls from your TV set! This will adjust the difference between the darkest and lightest parts of the input image. If you use 0% you end up with black just like with brightness, so not too interesting. However as you increase the value towards 100% the difference in darkness changes until you hit 100% and its the original image again. You can also go beyond 100% for this effect too, which increases the difference between light and dark colors even more.

Original contrast(200%)

blur(radius) If you want a soft edge for your content, you can add a blur. This one looks like the classic Vaseline on a sheet of glass look that used to be a popular movie making technique. It smudges all the colors together and spreads their effect out - kind of like when your eyes are out of focus. The radius parameter affects how many pixels on the screen blend into each other, so a larger value will create more blur. Zero of course leaves the image unchanged.

Original blur(10px)

8/11

drop-shadow(shadow) Its so nice to be able to make your content look like its outside in the sun with a shadow on the ground behind it, and that of course is what drop-shadow does. It takes a snapshot of the image, makes it a single color, blurs it, then offsets the result a bit so it looks like a shadow of the original content. The shadow parameter passed in is a bit more complicated than just a single value. It is a series of values separated by a space - and some values are optional too! The shadow values control where the shadow is placed, how much blur is applied, the color of the shadow, etc. For full details of what the shadow values do, the CSS3 Backgrounds specification defines box-shadow in great detail. A few examples below should give you a decent idea of what the various possibilities are.

drop-shadow(16px 16px 20px black)

drop-shadow(10px -16px 30px purple)

This is another filter operation that is similar to existing CSS functionality available via the box-shadow property. Using the filter approach means that it may get hardware accelerated by some browsers as we described for the opacity operation above. url referencing SVG filters Since filters originated as part of SVG, its only logical that you should be able to style your content using an SVG filter. This is easy with the current filter property proposal. All filters in SVG are defined with an id attribute that can be used to reference the filter effect. So, to use any SVG filter from CSS all you need to do is reference it using the url syntax. For example, the SVG markup for a filter could be something like: <filter id=foo>...</filter> then from CSS you could do something as simple as: div { +filter: url(#foo); } and voila! All the <div>s in your document will be styled with the SVG filter definitions. custom (coming soon) Coming soon on the horizon are custom filters. These tap into the power of your graphics GPU to use a special shading language to perform amazing effects bounded only by your own imagination. This part of the filter specification is still under discussion and in flux, but as soon as this starts to come to a browser near you, well be sure to write more about what is possible.
9/11

PERFORMANCE CONSIDERATIONS
One thing that every web developer cares about is performance of their web page or application. CSS filters are a powerful tool for visual effects, but at the same time might have an impact on the performance of your site. Understanding what they do and how this affects performance matters, especially if you want your site to work well on mobile devices if they support CSS filters. Firstly, not all filters are created equal! In fact, most filters will run really quickly on any platform and have very minor performance impact. However, filters that do any kind of blurring tend to be slower than the others. This of course means blur and drop-shadow. This doesnt mean you shouldnt use them but understanding how they work might help. When you do a blur, it mixes the colors from pixels all around the output pixel to generate a blurred result. So, say if your radius parameter is 2, then the filter needs to look at 2 pixels in every direction around each output pixel to generate the mixed color. This happens for each output pixel, so that means a lot of calculations that just get bigger when you increase the radius. Since blur looks in every direction, doubling the radius means you need to look at 4 times as many pixels so in fact its 4 times slower for each doubling of the radius. The drop-shadow filter contains a blur as part of its effect, so it too behaves just like blur when you change the radius and spread parts of the shadow parameter. All is not lost with blur since on some platforms its possible to use the GPU to accelerate it, but thats not necessarily going to be available in every browser. When in doubt the best thing is to experiment with the radius that gives you the effect you want, then try to reduce it as much as possible while still maintaining an acceptable visual effect. Tuning this way will make your users happier especially if they use your site from a phone. If youre using url based filters that reference SVG filters, they can contain any arbitrary filter effect so be aware that they too could be slow, so try to make sure you know what the filter effect does and experiment on a mobile device to make sure the performance is OK.

AVAILABILITY IN MODERN BROWSERS


Right now a number of the CSS filter effects are being made available in WebKit based browsers and Mozilla. We expect to see them soon in Opera as well as IE10. As the specification is still under development, some browser vendors have implemented this stuff using vendor prefixes. So in WebKit you need to use -webkit-filter, in Mozilla you will need to use -moz-filter and keep your eye out for other browser implementations as they appear. Not all browsers will support all filter effects right away, so your mileage will vary. Presently, the Mozilla browser supports only the filter: url() function - without the vendor prefix, as that implementation predates the other effects functionsw. Weve summarized the CSS filter effects available in the various browsers below with rough performance indicators for when theyre implemented in software. Note, that a number of modern browsers are beginning to implement these in hardware (GPU accelerated). When these are built with GPU support, performance will be greatly improved for the slower effects.

10/11

As usual, testing on different browsers is the best way to evaluate the performance. Filter Effect grayscale sepia saturate hue-rotate invert opacity brightness contrast blur drop-shadow url() Browser Support Chrome Chrome Chrome Chrome Chrome Chrome Chrome Chrome Chrome Chrome Chrome, Mozilla Performance very fast very fast very fast fast very fast can be slow fast fast slow unless accelerated can be slow varies, fast to slow

OTHER GOOD RESOURCES


An awesome interactive abstract painting with filters application which lets you experiment and share your artwork Be sure to check out Eric Bidelmans excellent interactive filter page A great tutorial about filters with examples The official W3C Filter Effects 1.0 draft specification https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html Example UI created using filters The original post on HTML5 ROCKS: http://www.html5rocks.com/en/tutorials/filters/understanding-css/

ABOUT THIS ARTICLE


Alex Danilo is the Co-founder and CTO at Abbra in Sydney, Australia. Abbra develops high performance rasterization software for rich media experiences using standards-based technologies such as SVG, HTML and CSS. Alex specializes in management, recruiting, hardcore embedded performance architecture, graphics algorithms and real-time systems.

ONLINE RESOURCES W3C Filter Effects 1.0 Draft Specification https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html


Applying SVG Effects to HTML Content http://robert.ocallahan.org/2008/06/applying-svg-effects-to-htmlcontent_04.html CSS3 Backgrounds http://www.w3.org/TR/css3-background/#the-box-shadow

http://www.abbra.com @alexanderdanilo

appliness

FOCUS ON CSS

WebKit, and Filters, and Shaders! Oh, my!

CSS Shaders are a new and relatively easy way to bring cinematic effects to the web. You can find out all about them on the ADC, on the Adobe & HTML site or you can read the actual W3 draft proposal.

background
While there are many articles out there showing how to use shaders, actually building your own custom shader is another story. Thats what were going to do here. One caveat though CSS filters and shaders are not completely mainstream yet. Filters need a WebKit nightly or at least Chrome 18.0.976.0 to be seen. While there is CSS shaders support available in recent versions of Chrome (disabled by default), the demonstrations below use the latest notations and restrictions (more on that later). If you want to see the demos live, youll need to get Adobes WebKit prototype from https://github.com/adobe/webkit/downloads. Id recommend grabbing that so you can play around with it yourself. Note This page will auto-detect your browsers capabilities and will show you a video if you dont have support for the demo. If your browser does support the necessary feature, youll be able to see the demo inline instead.

Filters First
Filter effects let you declare image effects on various part of your HTML. Swipe the image below and it should have a sepia filter applied to it:

freefoto.com The way we did that was with the following css style: #img1:hover { -webkit-filter: sepia(100%); }

When you hover over img1, the sepia filter is applied to the image. But filters can be applied to any HTML. We see below how easy it is to blur some text. Swipe the text below and it should blur slightly.

That was done simply with the following css:

That was done simply with the following css: #text1:hover {-webkit-filter: blur(2px); } Its pretty straightforward. There are all kinds of filters available, including: grayscale(amount) sepia(amount) saturate(amount)
2/7

hue-rotate(angle)

invert(amount) opacity(amount) brightness(amount) contrast(amount) blur(radius) drop shadow(shadow)

Prefixes
If youll notice above, we used -webkit-filter, not simply filter. I used the -webkit prefix because that is what is working right now. Ultimately, for compatibility you should declare the filter multiple times, one with each vendor prefix, as in: #myDiv { -webkit-filter: <Google Chrome & Safari filter definition>; -moz-filter: <Firefox filter definition>; -ms-filter: <Internet Explorer filter definition>; -o-filter: <Opera filter definition>; } All of the examples here just use the -webkit filter to keep the examples simple and to make it as straightforward as possible for you to get the examples working on your own. Now what if we want to extend filters and create or reuse a custom filter? Thats where shaders come in.

CSS Shaders
There are 2 types of shaders: Fragment shaders - Also known as pixel shaders, operate on pixel color values. A typically small parameterized program calculates the color value of each pixel of the declared content. Vertex shaders - Operate on point coordinates (vertices). The content is broken up into a grid of vertices based on the resolution declared in the CSS. A similarly small parameterized program is used to transform each vertex in 3D space. The result is then projected back onto a 2D plane and rendered in the browser. Shaders are declared using the same -webkit-filter css style but use a custom filter, as in: -webkit-filter: custom(<vertex shader> [<fragment shader>] [, <vertex mesh>][, params...]) For example, you could have something like: -webkit-filter: custom(url(shaders/myvshader.vs) url(shaders/myfshader.fs), 20 20, amt 1) where 20 20 defines the mesh resolution for the Vertex shader and amt 1 is a parameter passed in to the shaders. If you dont want one of the shaders, just specify none instead, or you can leave the fragment shader out altogether if you want:

3/7

-webkit-filter: custom(url(shaders/myvshader.vs), amt 1) or -webkit-filter: custom(none url(shaders/myfshader.fs)) Shader programs are written using the OpenGL ES shading language. Thats right, OpenGL. WebGL has the same concept of shaders and also uses the OpenGL ES shading language. Ok, lets have some fun here. Remember, if you want to see the demos running inline, you need to be running the WebKit prototype. If not, youll just see videos below: Simple Fragment Shader

Notice when the mouse moves over the text and image, it slowly turns to grayscale. This is achieved with a combination fragment shader and css transition. In this case we have a div which contains some text and images. The div is declared with a class attribute named shader. The name itself doesnt matter. Its just a way of identifying the div. As with filters, the declaration lies in the css styling:

.shader{ -webkit-filter: custom(none url(shaders/grayscale.fs), amount 0); -webkit-transition: -webkit-filter linear 1s; } .shader:hover{ -webkit-filter: custom(none url(shaders/grayscale.fs), amount 1); } In this case there is no vertex shader, but there is a fragment shader. Note that we didnt have to use a custom shader to achieve the grayscale effect. We could have simply used a standard filter, with something like: .shader { filter: grayscale(0); transition: filter 2s linear;} .shader:hover {filter: grayscale(1); } But I wanted to show you a simple example so we could better dissect it. Lets take a look at grayscale.fs: precision mediump float; // This uniform value is passed in using CSS. uniform float amount; void main() { float oneMinusAmount = 1.0 - amount; css_ColorMatrix = mat4( (0.2126 + 0.7874 * oneMinusAmount), (0.7152 - 0.7152 * oneMinusAmount), (0.0722 - 0.0722 * oneMinusAmount),

4/7

0.0, (0.2126 - 0.2126 * oneMinusAmount), (0.7152 + 0.2848 * oneMinusAmount), (0.0722 - 0.0722 * oneMinusAmount), 0.0, (0.2126 - 0.2126 * oneMinusAmount), (0.7152 - 0.7152 * oneMinusAmount), (0.0722 + 0.9278 * oneMinusAmount), 0.0, } 0.0, 0.0, 0.0, 1.0);

First we set the required precision qualifier. This declares a minimum range and precision the underlying shader engine must use when storing variables. precision mediump float

In this case it means that floats should be stored with the minimum range and precision required for the fragment language. uniform float amount; Uniforms are variables passed in from the web browser to the shaders. In the case of this grayscale fragment shader, the same amount will be passed in for every pixel color calculation. Notice how we declared the amount in the css: -webkit-filter: custom(none url(shaders/grayscale.fs), amount 1); If we had declared a vertex shader, the amount uniform would have been passed into that as well. The other variable type worth noting here is varying. Any variables of type varying will be passed from one shader to another. A variable set in a vertex shader can then be passed in to a fragment shader. An example of this would be determining the 3D shape of something in the vertex shader, and then using those coordinates to determine shading in the fragment shader. Now, notice in grayscale.fs how we dont explicitly calculate a new color. Instead we calculate a color matrix css_ColorMatrix. The color matrix is actually pre-multiplied against each color value to calculate new colors, as in: | | | | | R G B A 1 | | | | | | | | | | a00 a10 a20 a30 0 a01 a11 a21 a31 0 a02 a12 a22 a32 0 a03 a13 a23 a33 0 a04 a14 a24 a34 1 | | R | | G | * | B | | A | | 1 | | | | |

You can read more details on the color matrix from the current filter spec draft. You may be thinking at this point, Why dont we simply calculate a new color? The shader language even has the notion of gl_FragColor. That seems to be a more straightforward and powerful option. Well, it turns out there are some potentially serious security concerns for shaders

5/7

Shaders & Security


Shaders are intended to be reusable filter components. Its quite possible that there will be a situation where a shader might not be sourced from the same trusted domain as the content upon which it is operating. Heres a crazy thought write a shader that, depending on the color of each pixel, takes more or less time to execute. Then, write some nice little bit of JavaScript that measures the execution time of the shader and, heres the really fun part, infers potentially protected data from that rendered content. Is that even possible? It turns out unfortunately that this is not such a far-fetched idea as one would hope. This has been prototyped and proven to work in WebGL. As a result, there is a lot discussion going on at present trying to determine the safest restrictions that can be imposed on shaders that still leave shaders as an extremely valuable tool in your design belt. The current proposal is to restrict any access to the original content in the filter. In the case of a fragment shader, instead of taking the current color and applying some calculation on it, we calculate a transform that the filter engine will use to calculate the colors on its own. Its still extremely useful; just a different way of thinking about things. And now back to our previous shader development I have to admit, that last grayscale example was a little boring. We just did in the custom filter what we easily could have done with a standard grayscale filter. But what if we want to change the color matrix for every pixel rendered? Aha! Now things start to get interesting. Lets look at this fragment shader: precision mediump float; uniform float amount; uniform float resX; uniform float resY; void main( void ) { float dx = (resX / 2.0) - gl_FragCoord.x; float dy = (resY / 2.0) - gl_FragCoord.y; float k = (sin(amount * 0.4) + 1.0) * 0.5; float d = (dx * dx + dy * dy) * k; float float float float r g b a = = = = (sin(amount (sin(amount (sin(amount (sin(amount + * * * d * 0.029) + 1.0) * 0.5; 1.4 + d * 0.03) + 1.0) * 0.5; 10.0 + d * 0.03) + 1.0) * k; 5.0 + d * 0.03) + 1.0) * 0.5;

css_ColorMatrix = mat4( vec4(r, 0.0, 0.0, 0.0), vec4(0.0, g, 0.0, 0.0), vec4(0.0, 0.0, b, 0.0), vec4(0.0, 0.0, 0.0, a) );

You can find the actual filter here. This filter is an adaptation of this WebGL filter, found on the GLSL Sandbox. I highly recommend checking out this site if you want to see some of the interesting things that can be done with shaders. Like the grayscale filter, were still generating a css_ColorMatrix. But, in this instance we perform a series
6/7

of calculations based on gl_FragCoord. gl_FragCoord is a vec2 available to all fragment shaders that contains the window relative x & y coordinates of the current color pixel being transformed. The CSS which declares the shader is as follows: @-webkit-keyframes myanim { from { -webkit-filter: custom(none url(shaders/shader2.fs), amount 400, resX 1300, resY 100); } -webkit-filter: custom(none url(shaders/shader2.fs), amount 405, resX 800, resY 1400); } } .shader2:hover { -webkit-animation: myanim 4s ease 0s infinite alternate; } Note how we use a CSS animation to animate the input parameters to the shader. And here are the results: to {

That is some crazy stuff there, and weve only scratched the surface. The next series of articles will focus more on vertex shaders and well start to dig deeper into the shading language itself. Please stay tuned I hope to have some more fun articles shortly.

ABOUT THIS ARTICLE


Alan Greenblatt brings 25 years of software development and technical management expertise to his role as Flex Partner Solutions Architect at Adobe. He has been building and deploying large enterprise data integration applications using semantic web technologies on the backend and Adobe Flex on the front end since Flex was first introduced, and holds patents associated with that work.

ONLINE RESOURCES Adobe and HTML CSS Shaders http://html.adobe.com/webstandards/cssshaders/


ADC CSS Shaders http://www.adobe.com/devnet/html5/articles/css-shaders.html W3 Draft Proposal http://dvcs.w3.org/hg/FXTF/raw-file/tip/custom/index.html

http://blattchat.com/ @agreenblatt

appliness

FOCUS ON CSS

CSS OBJECT MODEL

Until Test the Web Forward I had just a vague idea of what CSS Object Model does. So, it was awesome to hear from and learn about the CSS Object Model from the spec co-editor Glenn Adams.

What it is?
The CSS Object Model specification provides APIs that allow you to query and manipulate styles once the browser reads and understands the stylesheets and inline styles that are used on the page that is being rendered. An older specification that standardizes this was called DOM Level 2 Style Specification. It was the first specification that provided ability to access and manipulate styles via JavaScript using the DOM API. The fragmented history of the web sadly means most of these APIs do not quite work the way they are intended to in many browsers. Glenn wrote in to state what the goals of the current specs are, which include: - Fully specify behavior that was left unstated, vague, or ambiguous in DOM-2 Style spec. - Remove functionality specified in DOM-2 Style that is not widely implemented and not perceived as necessary. - Add functionality not specified in DOM-2 Style that has been widely implemented and is viewed as sufficiently important. The APIs from the specification that have been implemented so far offer the

ou Playgr

nd

Difficulty
- rookie - intermediate - expert

- CSS - Testing ss.js - testharne

Todo list

- isolate - compare

- fix browsers

by Divya Manian

abilitiy to query rules specified in the stylesheets or a text representation of the styles in a stylesheet or the inline styles of an element within the rendered page. For example, you can get the value of margin of an element by using getComputedStyle(element,optional pseudoElement).margin. You can also get the full style declaration that applies to an element as a string by using getComputedStyl e(element,optional pseudoElement).cssText.

The CSSStyleDeclaration Object


The getComputedStyle method retuns what is known as a CSSStyleDeclaration object. It enumerates all style properties (& values). This is the object that is returned whenever you query for style information using: - document.styleSheet[0].cssRules[0].style - Element.style - document.getOverrideStyle (unimplemented in most browsers, but would be useful for getting/ setting hover, and other pseudo-classes). - window.getComputedStyle The returned object itself can be changed (it is mutable which means you can set a style property like Element.style.margin = 20px) in all cases except the last. If you try to change a property of the object returned by window.getComputedStyle(Element), you would get an exception.

CSS Rules
Rules within stylesheets have an object model too. There are 6 kinds of CSS rules that could apply: - Style rules (e.g h1 {} or #main a {color: red; }) - @import rules (e.g. @import url(main.css)) - Page rules (e.g. @page :first {color: red; }) - @font-face rules (e.g. @font-face {}) - Namespace rules (e.g. @namespace svg http://svg.org) - Media rules (e.g. @media (min-width: 200px)) Not only that but you can even access the individual selectors that you specified in your style sheet. The values for properties in selectors are also serialised. How these values are serialised has also been documented in the specification. For example, if an element has a style property set (inline or set from within a stylesheet) like so margin: 20px 20px 20px 20px;, the specification states that when you access the style using cssText it should return margin: 20px;.

2/5

Testing CSS Values


The above serialization of CSS values seemed trivial and I thought would be a good test to start with. So, I wrote a small test:

Source code of this test: <!doctype html> <head> <title>CSS OM: CSS Values</title> <link rel=author title=Divya Manian href=mailto:manian@adobe.com> <link rel=help href=http://www.w3.org/TR/cssom/#css-values> <meta name=flags content=cssom> <meta name=assert content=The style value should be serialized to margin: 20px;> <script src=./testharness.js></script> <script src=./testharnessreport.js></script> </head> <body> <div id=cssomtestElm></div> <div id=log></div> <script> var testElm = document.getElementById(cssomtestElm); // Set the transform document.getElementById(cssomtestElm).style.margin = 20px 20px 20px 20px; // Verify that the transform was set as expected test(function() {assert_equals( document.getElementById(cssomtestElm).style.cssText, //Actual

3/5

margin: 20px;, //Expected Margin should be serialized as margin: 20px;)}, //Description margin_20px_20px); //name </script> </body> </html> The results were interesting: - Firefox & IE 9 were the only browsers that returned the expected value of margin: 20px - Chrome returned margin: 20px; (note the whitespace after the semi-colon) - Opera bizarrely returns margin-top: 20px; margin-bottom: 20px; margin-left: 20px; margin-right: 20px (also note the missing last semi-colon). - Safari returned margin-top: 20px; margin-right: 20px; margin-bottom: 20px; margin-left: 20px; (note the space after the last semi-colon). Imagine the frustration of someone trying to write a CSS Style editor and wanting to show CSS style rules correctly! Glenn tells me that radical differences like these exist because the original DOM 2 Style spec did not document the serialization rules (he also pointed to this thread that discusses which properties get serialized or not).

Hopefully, because of Test the Web Forward, we can have more such tests in the future to ensure all browsers implement these APIs and specifications correctly. There are many other APIs available in the CSS OM. Interestingly, I was made aware of the longest property name (proprietary though) in existence: -webkit-match-nearest-mail-blockquote-color (thanks to Andreas Kling this is no longer the case, it is now -webkit-border-bottom-right-radius) (I wonder what is the shortest?).

4/5

If you are interested in writing and contributing CSS tests, first make an account (please do make sure to check the box for Request Repository Write Access) and then follow along with this presentation by Jacob Goldstein & Rebecca Hauck:

ABOUT THIS ARTICLE


Divya Manian is part of the Adobe Web Platform Team in San Francisco. She made the jump from developing device drivers for Motorola phones to designing websites and has not looked back since. She takes her duties as an Open Web vigilante seriously which has resulted in collaborative projects such as HTML5 Please and HTML5 Boilerplate.

ONLINE RESOURCES Test the Web Forward http://testthewebforward.org/


Divyas blog http://nimbupani.com/ HTML & Adobe http://html.adobe.com

http://nimbupani.com/ @divya

appliness

VIDEO TUTORIAL

INTRO TO BACKSTACK A BACKBONE.JS VIEWS NAVIGATION LIBRARY


by Piotr Walczyszyn
Recently Ive been working on several projects using PhoneGap/Cordova. These projects had a common requirement, and that was to have a custom UI look while preserving the interactions and feel that are common to mobile devices. Because of the custom UI look requirement I didnt want to use any of the available mobile UI frameworks like jQuery Mobile, Sencha Touch, or jQTouch. Of course, those frameworks are really great and can save you ton of work, but at the same time they come with their own look-and-feel that often can be hard to re-skin to achieve what the app designer has proposed. That is why I decided to stick with pure HTML/CSS elements as much as possible and in some cases to build missing components from scratch. That is how BackStack came to life. In few simple words BackStack is an extension for Backbone. js that allows you to navigate between app views with nice mobile-style slide transitions, fade transitions, and no-effect transitions. To play with BackStack yourself you can check out this demo site (it may not work well on non-WebKit based browsers, which is fine if you are doing PhoneGap/Cordova development). You can read more about it and download it from its GitHub project site located here. And if reading about BackStack is not enough for you, then watch the video.

GEt the source code

Demo site: http://pwalczyszyn.github.com/backstack/ Download on GitHub: https://github.com/pwalczyszyn/backstack Piotrs blog: http://outof.me/

appliness

SHOWCASE

Every month, we showcase killer apps developed with web standards. If you want to showcase your work, contact us by email - contact@appliness.com. This month, we have been very impressed by the quality of a game developed in HTML5 and deployed on mobile devices thanks to PhoneGap.

what the photo?

Do you enjoy sharing photos and playing games with your friends? Take turns racing the clock to guess the photo as the tiles disappear in this turn-based social game. The faster you answer, the more coins you win! Be goofy and let your creativity flow as you snap photos and transform them into games throughout your day. Draw out your best imagination. Developed with web standards and built with PhoneGap, this addictive game is available on Android, iOS devices.

PhoneGap let us leverage our HTML5 development skills, while giving us the flexibility to integrate native code where it made sense. Maintaining a single codebase for iOS and Android development has allowed us to iterate quickly on both platforms. Jonah Schwartz, Co-Founder & CTO Rumpus
More information on: http://www.rumpus.com/

appliness

HELTER SKELTER NEWS

Fresh news about HTML and Javascript collected by Brian Rinaldi - remotesynthesis.com
JavaScript Profiling With The Chrome Developer Tools via Zack Grossbart

Example of a dynamic HTML5 datalist controlvia Raymond Camden

Animated CSS3 Loading Bars with SVG Backgrounds via Johnny Simpson

How CSS Handles Errors - Tab Completion via Tab Atkins Jr Crafting Minimal Circular 3D Buttons with CSS via Brandon Pierce Web Audio API Getting started via CreativeJS

CSS variables via Stoyan Stefanov

An Introduction to Content Security Policy via Mike West

Managing Client-side Templates with RequireJS by Eric Feminella

appliness

HELTER SKELTER NEWS

Key Principles of Maintainable JavaScript via Jonathan Creamer Your First Polyfill via Jack Franklin Feature Detection vs Browser Detection via Joe Zim

how this works in JavaScript via Alex Young What is the Execution Context & Stack in JavaScript? via David Shariff.

Working with CSS Regions and Shadow DOM via Razvan Caliman

Using semantic HTML via Terry Ryan

Node & Express Todo App: Redis via Jack Franklin

Crowdsource Testing with QUnit and Browserscope by Razvan Caliman

MORE NEWS ON remotesynthesis.com

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 CHAE L
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 ON 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

DAVID CHR I STO P HE


Christophe is a Developer Evangelist for Adobe where he focuses on Web Standards, Mobile, and Rich HTML Applications with a special focus on Enterprise Integration. In this role, Christophe has helped some of the largest financial services companies design, architect and implement some of their most mission critical applications. He was one of the initial members of the Flex Product Team in 2003. In his previous role at Macromedia, Christophe worked on JRun, the companys J2EE application server. Before joining Macromedia, Christophe was managing Java and Internet Applications Evangelism at Sybase and Powersoft. Christophe has been a regular speaker at conferences worldwide for the last 15 years.

COENRAETS

David Deraedt likes to share his love for coding wherever he has the opportunity, in particular at Adobe where he works as a consultant specializing in frontend application development using web technologies.

DERAEDT

D I V YA

MANIAN

BR 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.

Divya Manian is part of the Adobe Web Platform Team in San Francisco. She made the jump from developing device drivers for Motorola phones to designing websites and has not looked back since. She takes her duties as an Open Web vigilante seriously which has resulted in collaborative projects such as HTML5 Please and HTML5 Boilerplate.

RINALDI

TERRENCE
Terrence Ryan is a Worldwide Developer Evangelist for Adobe. His job basically entails traveling the world and talking about the developer tools and technologies that Adobe has to offer or that evangelists support.

RYAN

P I OTR
Walczyszyn
Piotr Walczyszyn is a technology geek leaving in Warsaw, Poland, where he was born. outof.me is his new blog in which he wants to express his current interests and share some of his work. Technologies change; new trends come and go. These days nobody talks about RIAs (Rich Internet Applications) anymore, and he thinkd this phrase has become almost pass although its main concepts have not.

AN D RE W
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.

TR I CE

M A I L E
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

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.

W I L SON

RE

HO L L Y
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.

Schinsky

Appliness is a digital magazine written by passionate web developers. You can follow our activity on Facebook, Twitter or Google+.

W FO
o t t n a w ? u e Yo ribut t n co

LL

US

If you want to contribute writing articles or showcasing your app, feel free to contact us. We are permanently looking for new contributions and content to cover all the aspect of application development with web standards. We are also opened to suggestions. The Give us feedback form on our website is the best way to contact the team.

GIVE US FEEDBACK

CLICK HERE TO CONTACT US

CONTR

IBUTE

You might also like