Appliness #9 – December 2012

123

Transcript of Appliness #9 – December 2012

Page 1: Appliness #9 – December 2012
Page 2: Appliness #9 – December 2012

appliness(THE FIRST DIGITAL MAGAZINE FOR WEB APPLICATION DEVELOPERS

WELCOME TO APPLINESS. THE CONTRIBUTORS OF THIS FREE MAGAZINE ARE ALL PROFESSIONAL AND PAS-SIONATE 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 9TH ISSUE OF THIS MAGAZINE.

TABLE OF CONTENTS

NEWS ABOUT HTML AND JAVASCRIPTby Brian Rinaldi

HELTER SKELTER NEWS

NAVIGATION GUIDEREAD NAVIGATE

MOVE TO THE NEXT ARTICLE BY A HORIZONTAL SWIPE

READ THROUGH THE ARTICLE BY A VERTICAL SWIPE

GO BACK TO THE LIBRARY

MOVE TO THE PREVIOUSARTICLE

DISPLAY THE TABLE OF CONTENTS

VISUALLY BROWSE ALL THE ARTICLES

TUTORIALS

JAVASCRIPT: FUNCTION INVOCATION PATTERNSby Barry Steyn

WRITING FAST JAVASCRIPTby Addy Osmani

WHY I CHOSE SASSby Kianosh Pourian

COLLIE TUTORIALS by Sangmin Shim

PLUGGING INTO SOCKET.IO: ADVANCEDby Joe Zimmerman

DESIGNING JAVASCRIPT APIS by Brett van Zuiden

DYNAMICALLY LOADING A STYLE SHEET BASED ON WEATHER CONDITIONS by Raymond Camden

FUN WITH BUILT-IN CSS FILTERS by CJ Gammon

GETTING STARTED WITH JAVASCRIPT MAPS by Antanas Marcelionis

INTERVIEW

KEVIN LYNCH - CTO AT ADOBE Exclusive interview by Maile Valentine & Michaël Chaize

BUILDING YOUR FIRST BRACKETS EXTENSION by David Deraedt

CLEARING FLOATS EVEN IN MODERN BROWSERS by Louis Lazaris

MISSION IMPOSSIBLE: IPAD MINI DETECTIONby Maximiliano Firtman

EMBED PHONEGAP AS A SUBVIEW IN YOUR NATIVE IOS APPLICATIONby Holly Schinsky

JS ADOLESCENCE by James Padosley

TUTORIALS

RESPONSIVE MENU CONCEPTSby Tim Pietrusky

JAVASCRIPT APIS YOU’VE NEVER HEARD OFby Nicholas C. Zakas

Page 3: Appliness #9 – December 2012

appliness( DON’T WORRY, BE APPLI

by Barry Steyn

JAVASCRIPT: FUNCTION INVOCATION PATTERNSCHECK OUT THESE COOL TOOLS FOR CREATING INTERACTIVE MAPS USING SVG TO RENDER MAPS.

JavaScript has been described as a Functional Oriented Language (this as opposed to Object Oriented Language). The reason is because functions in JavaScript do more than just separate logic into execution units, functions are first class citizens that also provide scope and the ability to create objects. Having such a heavy reliance upon functions is both a blessing and a curse: It’s a blessing because it makes the language light weight and fast (the main goal of its original development), but it is a curse because you can very easily shoot yourself in the foot if you don’t know what you are doing.

One concern with JavaScript functions is how different invocation patterns can produce vastly different results. This post explains the four patterns, how to use them and what to watch out for. The four invoca-tion patterns are:

1. Method Invocation

2. Function Invocation

3. Constructor Invocation

4. Apply And Call Invocation

FUNCTION EXECUTION

JavaScript (like all languages these days) has the ability to modularise logic in functions which can be invoked at any point within the execution. Invok-ing a function suspends execution of the current function, passing controls

Page 4: Appliness #9 – December 2012

and parameters to the invoked function. In addition, a parameter called this is also passed to the func-tion. The invocation operator is a pair of round brackets (), that can contain zero or more expressions separated by a comma.

Unfortunately, there is more than one pattern that can be used to invoke functions. These patterns are not nice-to-know: They are absolutely essential to know. This is because invoking a function with a different pattern can produce a vastly different result. I believe that this is a language design error in JavaScript, and had the language been designed with more thought (and less haste), this would not have been such a big issue.

THE FOUR INVOCATION PATTERNS

Even though there are is only one invocation operator (), there are four invocation patterns. Each pat-tern differs in how the this parameter is initialised.

METHOD INVOCATION

When a function is part of an object, it is called a method. Method invocation is the pattern of invoking a function that is part of an object. For example:

var obj = { value: 0, increment: function() { this.value+=1; }};

obj.increment(); //Method invocation

Method invocation is identified when a function is preceded by object., where object is the name of some object. JavaScript will set the this parameter to the object where the method was invoked on. In the example above, this would be set to obj. JavaScript binds this at execution (also known as late binding).

FUNCTION INVOCATION

Function invocation is performed by invoking a function using ():

add(2,3); //5

When using the function invocation pattern, this is set to the global object. This was a mistake in the JavaScript language! Blindly binding this to the global object can destroy its current context. It is noti-cable when using an inner function within a method function. An example should explain things better:

var value = 500; //Global variablevar obj = { value: 0, increment: function() { this.value++;

var innerFunction = function() { alert(this.value); }

innerFunction(); //Function invocation pattern 2/5

Page 5: Appliness #9 – December 2012

}}obj.increment(); //Method invocation pattern

What do you think will be printed to screen? For those that answered 1, you are wrong (but don’t be too hard on yourselves, this is because JavaScript does not do things very well). The real answer is 500. Note that innerFunction is called using the function invocation pattern, therefore this is set to the global object. The result is that innerFunction (again, it is important to note that it is invoked with func-tion pattern) will not have this set to current object. Instead, it is set to the global object, where value is defined as 500. I stress that this is bad language design; the increment function was invoked with the method invocation pattern, and so it is natural to assume the this should always point to the current function when used inside it.

There is an easy way to get round this problem, but it is in my opinion a hack. One gets around this prob-lem by assigning a variable (by convention, it is named that) to this inside the function (aside: This works because functions in JavaScript are closures):

var value = 500; //Global variablevar obj = { value: 0, increment: function() { var that = this; that.value++;

var innerFunction = function() { alert(that.value); }

innerFunction(); //Function invocation pattern }}obj.increment();

If this could be bound to the current object whose scope it is called in, function and method invocations would be identical.

CONSTRUCTOR INVOCATION

Warning: This is another JavaScript peculiarity! JavaScript is not a classical object oriented language. In-stead, it is a prototypical object oriented language, but the creators of JavaScript felt that people with classical object orientation experience (the vast majority) may be unhappy with a purely prototype aproach. This resulted in JavaScript being unsure of its prototypical nature and the worst thing happened: It mixed classical object orientation syntax with its prototypical nature. The result: A mess!

In classial object orientation, an object is an instantiation of a class. In C++ and Java, this instantiation is performed by using the new operator. This seems to be the inspiration behind the constructor invocation pattern...

The constructor invocation pattern involves putting the new operator just before the function is invoked. For example:

var Cheese = function(type) { var cheeseType = type;

3/5

Page 6: Appliness #9 – December 2012

return cheeseType;}

cheddar = new Cheese(“cheddar”); //new object returned, not the type.

Even though Cheese is a function object (and intuitively, one thinks of functions as running modularised pieces of code), we have created a new object by invoking the function with new in front of it. The this parameter will be set to the newly created object and the return operator of the function will have its behaviour altered. Regarding the behaviour of the return operator in constructor invocation, there are two cases:

1. If the function returns a simple type (number, string, boolean, null or undefined), the return will be ignored and instead this will be returned (which is set to the new object).

2. If the function returns an instance of Object (anything other than a simple type), then that object will be returned instead of returning this. This pattern is not used that often, but it can be very useful when combined with closures (see here for a great example).

For example:

var obj = { data : “Hello World”}

var Func1 = function() { return obj;}

var Func2 = function() { return “I am a simple type”;}

var f1 = new Func1(); //f1 is set to objvar f2 = new Func2(); //f2 is set to a new object

We might ignore this, and just use object literals to make objects, except that the makers of JavaScript have enabled a key feature of their language by using this pattern: Object creation with an arbitrary pro-totype link (see previous post for more details). This pattern is unintuitive and also potentially problem-atic. There is a remedy which was championed by Douglas Crockford: Augment Object with a create method that accomplishes what the constructor invocation pattern tries to do. I am happy to note that as of JavaScript 1.8.5, Object.create is a reality and can be used. Due to legacy, the constructor invoca-tion is still used often, and for backward compatability, will crop up quite frequently.

APPLY AND CALL INVOCATION

The apply pattern is not as badly thought out as the preceding patterns. The apply method allows man-ual invocation of a function with a means to pass the function an array of parameters and explicitly set the this parameter. Because functions are first class citizens, they are also objects and hence can have methods (functions) run on it. In fact, every function is linked to Function.prototype (see here for more details), and so methods can very easily be augmented to any function. The apply method is just an augmentation to every function as - I presume - it is defined on Function.prototype.

4/5

Page 7: Appliness #9 – December 2012

ABOUT THIS ARTICLE

Barry Steyn is an entrepreneur in the tech space. His formal education is in Math and Computer Sci-ence, but all he has ever wanted to do since he can remember is build things. Not anything mind you, but things that matter, that positively affect people. That’s why he is so attracted to computer science: he loves building programs. He also loves the build-ing process that is inherent with entrepreneurism. http://doctrina.org/ @barrysteyn

ONLINE RESOURCES

JavaScript: Why Understanding Scope and Closures Matterhttp://doctrina.org/JavaScript:Why-Understanding-Scope-And-Clo-sures-Matter.html

JavaScript: Object Prototypeshttp://doctrina.org/Javascript-Objects-Prototypes.html

JavaScript: Why Understanding Scope and Closures Matterhttp://doctrina.org/JavaScript:Why-Understanding-Scope-And-Closures-Matter.html

Apply takes two parameters: the first parameter is an object to bind the this parameter to, the second is an array which is mapped to the parameters:

var add = function(num1, num2) { return num1+num2;}

array = [3,4];add.apply(null,array); //7

In the example above, this is bound to null (the function is not an object, so it is not needed) and array is bound to num1 and num2. More interesting things can be done with the first parameter:

var obj = { data:’Hello World’}

var displayData = function() { alert(this.data);}

displayData(); //undefineddisplayData.apply(obj); //Hello World

The example above uses apply to bind this to obj. This results in being able to produce a value for this.data. Being able to expicitly assign a value to this is where the real value of apply comes about. Without this feature, we might as well use () to invoke functions.

JavaScript also has another invoker called call, that is identical to apply except that instead of taking an array of parameters, it takes an argument list. If JavaScript would implement function overriding, I think that call would be an overridden variant of apply. Therefore one talks about apply and call in the same vein.

CONCLUSION

For better or worse, JavaScript is about to take over the world. It is therefore very important that the peculiarities of the language be known and avoided. Learning how the four function invocation methods differ and how to avoid their pitfalls is fundamental to anyone who wants to use JavaScript. I hope this post has helped people when it comes to invoking functions.

Page 8: Appliness #9 – December 2012

appliness( DON’T WORRY, BE APPLI

by Addy Osmani

WRITING FAST, MEMORY-EFFICIENT JAVASCRIPT - PART 1JAVASCRIPT ENGINES SUCH AS GOOGLE’S V8 (CHROME, NODE) ARE SPECIFICALLY DESIGNED FOR THE FAST EXECUTION OF LARGE JAVASCRIPT APPLICATIONS. AS YOU DEVELOP, IF YOU CARE ABOUT MEM-ORY USAGE AND PERFORMANCE, YOU SHOULD BE AWARE OF SOME OF WHAT’S GOING ON IN YOUR USER’S BROWSER’S JAVASCRIPT ENGINE BEHIND THE SCENES.

PERFORM

Whether it’s V8, SpiderMonkey (Firefox), Carakan (Opera), Chakra (IE) or something else, doing so can help you better optimize your applications. That’s not to say one should optimize for a single browser or engine. Never do that.

You should, however, ask yourself questions such as:

- Is there anything I could be doing more efficiently in my code?

- What (common) optimizations do popular JavaScript engines make?

- What is the engine unable to optimize for, and is the garbage collector able to clean up what I’m expecting it to?

There are many common pitfalls when it comes to writing memory-efficient and fast code, and in this article we’re going to explore some test-proven approaches for writing code that performs better.

Page 9: Appliness #9 – December 2012

SO, HOW DOES JAVASCRIPT WORK IN V8?

While it’s possible to develop large-scale applications without a thorough understanding of JavaScript engines, any car owner will tell you they’ve looked under the hood at least once. As Chrome is my browser of choice, I’m going to talk a little about its JavaScript engine. V8 is made up of a few core pieces.

- A base compiler, which parses your JavaScript and generates native machine code before it is executed, rather than executing bytecode or simply interpreting it. This code is initially not highly optimized.

- V8 represents your objects in an object model. Objects are represented as associative arrays in JavaScript, but in V8 they are represented with hidden classes, which are an internal type system for optimized lookups.

- The runtime profiler monitors the system being run and identifies “hot” functions (i.e., code that ends up spending a long time running).

- An optimizing compiler recompiles and optimizes the “hot” code identified by the runtime profiler, and performs optimizations such as inlining (i.e., replacing a function call site with the body of the callee).

- V8 supports deoptimization, meaning the optimizing compiler can bail out of code generated if it discovers that some of the assumptions it made about the optimized code were too optimistic.

- It has a garbage collector. Understanding how it works can be just as important as the optimized JavaScript.

GARBAGE COLLECTION

Garbage collection is a form of memory management. It’s where we have the notion of a collector which attempts to reclaim memory occupied by objects that are no longer being used. In a garbage-collected language such as JavaScript, objects that are still referenced by your application are not cleaned up.

Manually de-referencing objects is not necessary in most cases. By simply putting the variables where they need to be (ideally, as local as possible, i.e., inside the function where they are used versus an outer scope), things should just work.

It’s not possible to force garbage collection in JavaScript. You wouldn’t want to do this, because the garbage collection process is controlled by the runtime, and it generally knows best when things should be cleaned up.

DE-REFERENCING MISCONCEPTIONS

In quite a few discussions online about reclaiming memory in JavaScript, the delete keyword is brought up, as although it was supposed to be used for just removing keys from a map, some developers think you can force de-referencing using it. Avoid using delete if you can. In the below example, delete o.x does a lot more harm than good behind the scenes, as it changes o‘s hidden class and makes it a generic slow object.

var o = { x: 1 }; delete o.x; // true o.x; // undefined

That said, you are almost certain to find references to delete in many popular JavaScript libraries – it does have a purpose in the language. The main takeaway here is to avoid modifying the structure of hot objects at runtime. JavaScript engines can detect such “hot” objects and attempt to optimize them. This is easier

2/13

Page 10: Appliness #9 – December 2012

if the object’s structure doesn’t heavily change over its lifetime and delete can trigger such changes.

There are also misconceptions about how null works. Setting an object reference to null doesn’t “null” the object. It sets the object reference to null. Using o.x = null is better than using delete, but it’s probably not even necessary.

var o = { x: 1 }; o = null;o; // nullo.x // TypeError

If this reference was the last reference to the object, the object is then eligible for garbage collection. If the reference was not the last reference to the object, the object is reachable and will not be garbage collected.

Another important note to be aware of is that global variables are not cleaned up by the garbage collector during the life of your page. Regardless of how long the page is open, variables scoped to the JavaScript runtime global object will stick around.

var myGlobalNamespace = {};

Globals are cleaned up when you refresh the page, navigate to a different page, close tabs or exit your browser. Function-scoped variables get cleaned up when a variable falls out of scope. When functions have exited and there aren’t any more references to it, the variable gets cleaned up.

RULES OF THUMB

To give the garbage collector a chance to collect as many objects as possible as early as possible, don’t hold on to objects you no longer need. This mostly happens automatically; here are a few things to keep in mind.

- As mentioned earlier, a better alternative to manual de-referencing is to use variables with an appropriate scope. I.e., instead of a global variable that’s nulled out, just use a function-local variable that goes out of scope when it’s no longer needed. This means cleaner code with less to worry about.

- Ensure that you’re unbinding event listeners where they are no longer required, especially when the DOM objects they’re bound to are about to be removed.

- If you’re using a data cache locally, make sure to clean that cache or use an aging mechanism to avoid large chunks of data being stored that you’re unlikely to reuse.

FUNCTIONS

Next, let’s look at functions. As we’ve already said, garbage collection works by reclaiming blocks of memory (objects) which are no longer reachable. To better illustrate this, here are some examples.

function foo() { var bar = new LargeObject(); bar.someCall();}

When foo returns, the object which bar points to is automatically available for garbage collection, because there is nothing left that has a reference to it.

Compare this to:

3/13

Page 11: Appliness #9 – December 2012

function foo() { var bar = new LargeObject(); bar.someCall(); return bar;}

// somewhere elsevar b = foo();

We now have a reference to the object which survives the call and persists until the caller assigns something else to b (or b goes out of scope).

CLOSURES

When you see a function that returns an inner function, that inner function will have access to the outer scope even after the outer function is executed. This is basically a closure — an expression which can work with variables set within a specific context. For example:

function sum (x) { function sumIt(y) { return x + y; }; return sumIt;}

// Usagevar sumA = sum(4);var sumB = sumA(3);console.log(sumB); // Returns 7

The function object created within the execution context of the call to sum can’t be garbage collected, as it’s referenced by a global variable and is still very much accessible. It can still be executed via sumA(n).

Let’s look at another example. Here, can we access largeStr?

var a = function () { var largeStr = new Array(1000000).join(‘x’); return function () { return largeStr; };}();

Yes, we can, via a(), so it’s not collected. How about this one?

var a = function () { var smallStr = ‘x’; var largeStr = new Array(1000000).join(‘x’); return function (n) { return smallStr; };}();

We can’t access it anymore and it’s a candidate for garbage collection.

4/13

Page 12: Appliness #9 – December 2012

TIMERS

One of the worst places to leak is in a loop, or in setTimeout()/setInterval(), but this is quite common.

Consider the following example.

var myObj = { callMeMaybe: function () { var myRef = this; var val = setTimeout(function () { console.log(‘Time is running out!’); myRef.callMeMaybe(); }, 1000); }};

If we then run:

myObj.callMeMaybe();

to begin the timer, we can see every second “Time is running out!” If we then run:

myObj = null;

The timer will still fire. myObj won’t be garbage collected as the closure passed to setTimeout has to be kept alive in order to be executed. In turn, it holds references to myObj as it captures myRef. This would be the same if we’d passed the closure to any other function, keeping references to it.

It is also worth keeping in mind that references inside a setTimeout/setInterval call, such as functions, will need to execute and complete before they can be garbage collected.

BE AWARE OF PERFORMANCE TRAPS

It’s important never to optimize code until you actually need to. This can’t be stressed enough. It’s easy to see a number of micro-benchmarks showing that N is more optimal than M in V8, but test it in a real module of code or in an actual application, and the true impact of those optimizations may be much more minimal than you were expecting.

Let’s say we want to create a module which:

- Takes a local source of data containing items with a numeric ID,

- Draws a table containing this data,

- Adds event handlers for toggling a class when a user clicks on any cell.

There are a few different factors to this problem, even though it’s quite straightforward to solve. How do we store the data? How do we efficiently draw the table and append it to the DOM? How do we handle events on this table optimally?

A first (naive) take on this problem might be to store each piece of available data in an object which we group into an array. One might use jQuery to iterate through the data and draw the table, then append it to the DOM. Finally, one might use event binding for adding the click behavior we desire.

5/13

Page 13: Appliness #9 – December 2012

NOTE: THIS IS NOT WHAT YOU SHOULD BE DOING

var moduleA = function () {

return {

data: dataArrayObject,

init: function () { this.addTable(); this.addEvents(); },

addTable: function () {

for (var i = 0; i < rows; i++) { $tr = $(‘<tr></tr>’); for (var j = 0; j < this.data.length; j++) { $tr.append(‘<td>’ + this.data[j][‘id’] + ‘</td>’); } $tr.appendTo($tbody); }

}, addEvents: function () { $(‘table td’).on(‘click’, function () { $(this).toggleClass(‘active’); }); }

};}();

Simple, but it gets the job done.

In this case however, the only data we’re iterating are IDs, a numeric property which could be more simply represented in a standard array. Interestingly, directly using DocumentFragment and native DOM methods are more optimal than using jQuery (in this manner) for our table generation, and of course, event delegation is typically more performant than binding each td individually.

Note that jQuery does use DocumentFragment internally behind the scenes, but in our example, the code is calling append() within a loop and each of these calls has little knowledge of the other so it may not be able to optimize for this example. This should hopefully not be a pain point, but be sure to benchmark your own code to be sure.

In our case, adding in these changes results in some good (expected) performance gains. Event delegation provides decent improvement over simply binding, and opting for documentFragment was a real booster.

var moduleD = function () {

return {

data: dataArray,

6/13

Page 14: Appliness #9 – December 2012

init: function () { this.addTable(); this.addEvents(); }, addTable: function () { var td, tr; var frag = document.createDocumentFragment(); var frag2 = document.createDocumentFragment();

for (var i = 0; i < rows; i++) { tr = document.createElement(‘tr’); for (var j = 0; j < this.data.length; j++) { td = document.createElement(‘td’); td.appendChild(document.createTextNode(this.data[j]));

frag2.appendChild(td); } tr.appendChild(frag2); frag.appendChild(tr); } tbody.appendChild(frag); }, addEvents: function () { $(‘table’).on(‘click’, ‘td’, function () { $(this).toggleClass(‘active’); }); }

};

}();

We might then look to other ways of improving performance. You may have read somewhere that using the prototypal pattern is more optimal than the module pattern (we confirmed it wasn’t earlier), or heard that using JavaScript templating frameworks are highly optimized. Sometimes they are, but use them because they make for readable code. Also, precompile! Let’s test and find out how true this hold in practice.

moduleG = function () {};

moduleG.prototype.data = dataArray;moduleG.prototype.init = function () { this.addTable(); this.addEvents();};moduleG.prototype.addTable = function () { var template = _.template($(‘#template’).text()); var html = template({‘data’ : this.data}); $tbody.append(html);};moduleG.prototype.addEvents = function () { $(‘table’).on(‘click’, ‘td’, function () { $(this).toggleClass(‘active’); });};

7/13

Page 15: Appliness #9 – December 2012

var modG = new moduleG();

As it turns out, in this case the performance benefits are negligible. Opting for templating and prototypes didn’t really offer anything more than what we had before. That said, performance isn’t really the reason modern developers use either of these things — it’s the readability, inheritance model and maintainability they bring to your codebase.

More complex problems include efficiently drawing images using canvas and manipulating pixel data with or without typed arrays

Always give micro-benchmarks a close lookover before exploring their use in your application. Some of you may recall the JavaScript templating shoot-off and the extended shoot-off that followed. You want to make sure that tests aren’t being impacted by constraints you’re unlikely to see in real world applications — test optimizations together in actual code.

V8 OPTIMIZATION TIPS

Whilst detailing every V8 optimization is outside the scope of this article, there are certainly many tips worth noting. Keep these in mind and you’ll reduce your chances of writing unperformant code.

Certain patterns will cause V8 to bail out of optimizations. A try-catch, for example, will cause such a bailout. For more information on what functions can and can’t be optimized, you can use --trace-opt file.js with the d8 shell utility that comes with V8.

If you care about speed, try very hard to keep your functions monomorphic, i.e., make sure that variables (including properties, arrays and function parameters) only ever contain objects with the same hidden class. For example, don’t do this:

function add(x, y) { return x+y;}

add(1, 2); add(‘a’,’b’); add(my_custom_object, undefined);

Don’t load from uninitialized or deleted elements. This won’t make a difference in output, but it will make things slower.

Don’t write enormous functions, as they are more difficult to optimize

For more tips, watch Daniel Clifford’s Google I/O talk Breaking the JavaScript Speed Limit with V8 as it covers these topics well. Optimizing For V8 — A Series is also worth a read.

OBJECTS VS. ARRAYS: WHICH SHOULD I USE?

- If you want to store a bunch of numbers, or a list of objects of the same type, use an array.

- If what you semantically need is an object with a bunch of properties (of varying types), use an object with properties. That’s pretty efficient in terms of memory, and it’s also pretty fast.

8/13

Page 16: Appliness #9 – December 2012

- Integer-indexed elements, regardless of whether they’re stored in an array or an object, are much faster to iterate over than object properties.

- Properties on objects are quite complex: they can be created with setters, and with differing enumerability and writability. Items in arrays aren’t able to be customized as heavily — they either exist or they don’t. At an engine level, this allows for more optimization in terms of organizing the memory representing the structure. This is particularly beneficial when the array contains numbers. For example, when you need vectors, don’t define a class with properties x, y, z; use an array instead.

There’s really only one major difference between objects and arrays in JavaScript, and that’s the arrays’ magic length property. If you’re keeping track of this property yourself, objects in V8 should be just as fast as arrays.

TIPS WHEN USING OBJECTS

Create objects using a constructor function. This ensures that all objects created with it have the same hidden class and helps avoid changing these classes. As an added benefit, it’s also slightly faster than Object.create().

There are no restrictions on the number of different object types you can use in your application or on their complexity (within reason: long prototype chains tend to hurt, and objects with only a handful of properties get a special representation that’s a bit faster than bigger objects). For “hot” objects, try to keep the prototype chains short and the field count low.

OBJECT CLONING

Object cloning is a common problem for app developers. While it’s possible to benchmark how well various implementations work with this type of problem in V8, be very careful when copying anything. Copying big things is generally slow — don’t do it. for..in loops in JavaScript are particularly bad for this, as they have a devilish specification and will likely never be fast in any engine for arbitrary objects.

When you absolutely do need to copy objects in a performance-critical code path (and you can’t get out of this situation), use an array or a custom “copy constructor” function which copies each property explicitly. This is probably the fastest way to do it:

function clone(original) { this.foo = original.foo; this.bar = original.bar;}var copy = new clone(original);

CACHED FUNCTIONS IN THE MODULE PATTERN

Caching your functions when using the module pattern can lead to performance improvements. See below for an example where the variation you’re probably used to seeing is slower as it forces new copies of the member functions to be created all the time.

Also note that using this approach can be significantly more optimal than just relying on the prototypal pattern (as confirmed by the jsPerf test).

9/13

Page 17: Appliness #9 – December 2012

Here is a test of prototype versus module pattern performance

// Prototypal pattern Klass1 = function () {} Klass1.prototype.foo = function () { log(‘foo’); } Klass1.prototype.bar = function () { log(‘bar’); }

// Module pattern Klass2 = function () { var foo = function () { log(‘foo’); }, bar = function () { log(‘bar’); };

return { foo: foo, bar: bar } }

// Module pattern with cached functions var FooFunction = function () { log(‘foo’); }; var BarFunction = function () { log(‘bar’); };

10/1

3

Page 18: Appliness #9 – December 2012

Klass3 = function () { return { foo: FooFunction, bar: BarFunction } }

// Iteration tests

// Prototypal var i = 1000, objs = []; while (i--) { var o = new Klass1() objs.push(new Klass1()); o.bar; o.foo; }

// Module pattern var i = 1000, objs = []; while (i--) { var o = Klass2() objs.push(Klass2()); o.bar; o.foo; }

// Module pattern with cached functions var i = 1000, objs = []; while (i--) { var o = Klass3() objs.push(Klass3()); o.bar; o.foo; }// See the test for full details

TIPS WHEN USING ARRAYS

Next let’s look at a few tips for arrays. In general, don’t delete array elements. It would make the array transition to a slower internal representation. When the key set becomes sparse, V8 will eventually switch elements to dictionary mode, which is even slower.

ARRAY LITERALS

Array literals are useful because they give a hint to the VM about the size and type of the array. They’re typically good for small to medium sized arrays.

11/1

3

Page 19: Appliness #9 – December 2012

// Here V8 can see that you want a 4-element array containing numbers:var a = [1, 2, 3, 4];

// Don’t do this:a = []; // Here V8 knows nothing about the arrayfor(var i = 1; i <= 4; i++) { a.push(i);}

STORAGE OF SINGLE TYPES VS. MIXED TYPES

It’s never a good idea to mix values of different types (e.g., numbers, strings, undefined or true/false) in the same array (i.e., var arr = [1, “1”, undefined, true, “true”])

Test of type inference performance

As we can see from the results, the array of ints is the fastest.

SPARSE ARRAYS VS. FULL ARRAYS

When you use sparse arrays, be aware that accessing elements in them is much slower than in full arrays. That’s because V8 doesn’t allocate a flat backing store for the elements if only a few of them are used. Instead, it manages them in a dictionary, which saves space, but costs time on access.

Test of sparse arrays versus full arrays.

The full array sum and sum of all elements on an array without zeros were actually the fastest. Whether the full array contains zeroes or not should not make a difference.

PACKED VS. HOLEY ARRAYS

Avoid “holes” in an array (created by deleting elements or a[x] = foo with x > a.length). Even if only a single element is deleted from an otherwise “full” array, things will be much slower.

Test of packed versus holey arrays.

PRE-ALLOCATING ARRAYS VS. GROWING AS YOU GO

Don’t pre-allocate large arrays (i.e., greater than 64K elements) to their maximum size, instead grow as you go. Before we get to the performance tests for this tip, keep in mind that this is specific to only some JavaScript engines.

Nitro (Safari) actually treats pre-allocated arrays more favorably. However, in other engines (V8, SpiderMonkey), not pre-allocating is more efficient.

12/1

3

Page 20: Appliness #9 – December 2012

ABOUT THIS ARTICLE

Addy Osmani is a Developer Programs Engineer on the Chrome team at Google. A passionate JavaScript developer, he has written open-source books like ‘Learning JavaScript Design Patterns’ and ‘Develop-ing Backbone Applications’, having also contributed to open-source projects like Modernizr and jQuery. He is currently working on ‘Yeoman’ - an opinion-ated workflow for building beautiful applications. http://addyosmani.com/blog/

@addyosmani

MORE ARTICLES FROM...

http://www.smashingmagazine.com/

Test of pre-allocated arrays.

// Empty arrayvar arr = [];for (var i = 0; i < 1000000; i++) { arr[i] = i;}

// Pre-allocated arrayvar arr = new Array(1000000);for (var i = 0; i < 1000000; i++) { arr[i] = i;}

Page 21: Appliness #9 – December 2012

appliness( DON’T WORRY, BE APPLI

by Addy Osmani

WRITING FAST, MEMORY-EFFICIENT JAVASCRIPT - PART 2JAVASCRIPT ENGINES SUCH AS GOOGLE’S V8 (CHROME, NODE) ARE SPECIFICALLY DESIGNED FOR THE FAST EXECUTION OF LARGE JAVASCRIPT APPLICATIONS. AS YOU DEVELOP, IF YOU CARE ABOUT MEM-ORY USAGE AND PERFORMANCE, YOU SHOULD BE AWARE OF SOME OF WHAT’S GOING ON IN YOUR USER’S BROWSER’S JAVASCRIPT ENGINE BEHIND THE SCENES.

OPTIMIZING YOUR APPLICATION

In the world of Web applications, speed is everything. No user wants a spreadsheet application to take seconds to sum up an entire column or a summary of their messages to take a minute before it’s ready. This is why squeezing every drop of extra performance you can out of code can sometimes be critical.

While understanding and improving your application performance is useful, it can also be difficult. We recommend the following steps to fix performance pain points:

- Measure it: Find the slow spots in your application (~45%)

- Understand it: Find out what the actual problem is (~45%)

- Fix it! (~10%)

Some of the tools and techniques recommended below can assist with this process.

BENCHMARKING

There are many ways to run benchmarks on JavaScript snippets to test their performance — the general assumption being that benchmarking is simply comparing two timestamps. One such pattern was pointed out by the jsPerf

Page 22: Appliness #9 – December 2012

team, and happens to be used in SunSpider‘s and Kraken‘s benchmark suites:

var totalTime, start = new Date, iterations = 1000;while (iterations--) { // Code snippet goes here}// totalTime → the number of milliseconds taken // to execute the code snippet 1000 timestotalTime = new Date - start;

Here, the code to be tested is placed within a loop and run a set number of times (e.g., six). After this, the start date is subtracted from the end date to find the time taken to perform the operations in the loop.

However, this oversimplifies how benchmarking should be done, especially if you want to run the benchmarks in multiple browsers and environments. Garbage collection itself can have an impact on your results. Even if you’re using a solution like window.performance, you still have to account for these pitfalls.

Regardless of whether you are simply running benchmarks against parts of your code, writing a test suite or coding a benchmarking library, there’s a lot more to JavaScript benchmarking than you might think. For a more detailed guide to benchmarking, I highly recommend reading JavaScript Benchmarking by Mathias Bynens and John-David Dalton.

PROFILING

The Chrome Developer Tools have good support for JavaScript profiling. You can use this feature to detect what functions are eating up the most of your time so that you can then go optimize them. This is important, as even small changes to your codebase can have serious impacts on your overall performance.

Profiling starts with obtaining a baseline for your code’s current performance, which can be discovered using the Timeline. This will tell us how long our code took to run. The Profiles tab then gives us a better view into what’s happening in our application. The JavaScript CPU profile shows us how much CPU time is being used by our code, the CSS selector profile shows us how much time is spent processing selectors and Heap snapshots show how much memory is being used by our objects.

Using these tools, we can isolate, tweak and reprofile to gauge whether changes we’re making to specific functions or operations are improving performance.

2/7

Page 23: Appliness #9 – December 2012

For a good introduction to profiling, read JavaScript Profiling With The Chrome Developer Tools, by Zack Grossbart.

Tip: Ideally, you want to ensure that your profiling isn’t being affected by extensions or applications you’ve installed, so run Chrome using the --user-data-dir <empty_directory> flag. Most of the time, this approach to optimization testing should be enough, but there are times when you need more. This is where V8 flags can be of help.

AVOIDING MEMORY LEAKS — THREE SNAPSHOT TECHNIQUES FOR DISCOVERY

Internally at Google, the Chrome Developer Tools are heavily used by teams such as Gmail to help us discover and squash memory leaks.

Some of the memory statistics that our teams care about include private memory usage, JavaScript heap size, DOM node counts, storage clearing, event listener counts and what’s going on with garbage collection. For those familiar with event-driven architectures, you might be interested to know that one of the most common issues we used to have were listen()’s without unlisten()’s (Closure) and missing dispose()’s for objects that create event listeners.

Luckily the DevTools can help locate some of these issues, and Loreena Lee has a fantastic presentation available documenting the “3 snapshot” technique for finding leaks within the DevTools that I can’t recommend reading through enough.

The gist of the technique is that you record a number of actions in your application, force a garbage collection, check if the number of DOM nodes doesn’t return to your expected baseline and then analyze three heap snapshots to determine if you have a leak.

MEMORY MANAGEMENT IN SINGLE-PAGE APPLICATIONS

Memory management is quite important when writing modern single-page applications (e.g., AngularJS, Backbone, Ember) as they almost never get refreshed. This means that memory leaks can become apparent quite quickly. This is a huge trap on mobile single-page applications, because of limited memory, and on long-running applications like email clients or social networking applications. With great power comes great responsibility.

There are various ways to prevent this. In Backbone, ensure you always dispose old views and references 3/7

Page 24: Appliness #9 – December 2012

using dispose() (currently available in Backbone (edge)). This function was recently added, and removes any handlers added in the view’s ‘events’ object, as well as any collection or model listeners where the view is passed as the third argument (callback context). dispose() is also called by the view’s remove(), taking care of the majority of basic memory cleanup needs when the element is cleared from the screen. Other libraries like Ember clean up observers when they detect that elements have been removed from view to avoid memory leaks.

Some sage advice from Derick Bailey:

“Other than being aware of how events work in terms of references, just follow the standard rules for manage memory in JavaScript and you’ll be fine. If you are loading data in to a Backbone collection full of User objects you want that collection to be cleaned up so it’s not using anymore memory, you must remove all references to the collection and the individual objects in it. Once you remove all references, things will be cleaned up. This is just the standard JavaScript garbage collection rule.”

In his article, Derick covers many of the common memory pitfalls when working with Backbone.js and how to fix them.

There is also a helpful tutorial available for debugging memory leaks in Node by Felix Geisendörfer worth reading, especially if it forms a part of your broader SPA stack.

MINIMIZING REFLOWS

When a browser has to recalculate the positions and geometrics of elements in a document for the purpose of re-rendering it, we call this reflow. Reflow is a user-blocking operation in the browser, so it’s helpful to understand how to improve reflow time.

You should batch methods that trigger reflow or that repaint, and use them sparingly. It’s important to process off DOM where possible. This is possible using DocumentFragment, a lightweight document object. Think of it as a way to extract a portion of a document’s tree, or create a new “fragment” of a document. Rather than constantly adding to the DOM using nodes, we can use document fragments to build up all we need and only perform a single insert into the DOM to avoid excessive reflow.

For example, let’s write a function that adds 20 divs to an element. Simply appending each new div directly to the element could trigger 20 reflows.

function addDivs(element) { var div; for (var i = 0; i < 20; i ++) { div = document.createElement(‘div’); div.innerHTML = ‘Heya!’; element.appendChild(div); }}

4/7

Page 25: Appliness #9 – December 2012

To work around this issue, we can use DocumentFragment, and instead, append each of our new divs to this. When appending to the DocumentFragment with a method like appendChild, all of the fragment’s children are appended to the element triggering only one reflow.

function addDivs(element) { var div; // Creates a new empty DocumentFragment. var fragment = document.createDocumentFragment(); for (var i = 0; i < 20; i ++) { div = document.createElement(‘a’); div.innerHTML = ‘Heya!’; fragment.appendChild(div); } element.appendChild(fragment);}

You can read more about this topic at Make the Web Faster, JavaScript Memory Optimization and Finding Memory Leaks.

JAVASCRIPT MEMORY LEAK DETECTOR

To help discover JavaScript memory leaks, two of my fellow Googlers (Marja Hölttä and Jochen Eisinger) developed a tool that works with the Chrome Developer Tools (specifically, the remote inspection protocol), and retrieves heap snapshots and detects what objects are causing leaks.

There’s a whole post on how to use the tool, and I encourage you to check it out or view the Leak Finder project page.

Some more information: In case you’re wondering why a tool like this isn’t already integrated with our Developer Tools, the reason is twofold. It was originally developed to help us catch some specific memory scenarios in the Closure Library, and it makes more sense as an external tool (or maybe even an extension if we get a heap profiling extension API in place).

V8 FLAGS FOR DEBUGGING OPTIMIZATIONS & GARBAGE COLLECTION

Chrome supports passing a number of flags directly to V8 via the js-flags flag to get more detailed output about what the engine is optimizing. For example, this traces V8 optimizations:

“/Applications/Google Chrome/Google Chrome” --js-flags=”--trace-opt --trace-deopt”

Windows users will want to run chrome.exe --js-flags=”--trace-opt --trace-deopt”

When developing your application, the following V8 flags can be used.

5/7

Page 26: Appliness #9 – December 2012

- trace-opt – log names of optimized functions and show where the optimizer is skipping code because it can’t figure something out.

- trace-deopt – log a list of code it had to deoptimize while running.

- trace-gc – logs a tracing line on each garbage collection.

V8’s tick-processing scripts mark optimized functions with an * (asterisk) and non-optimized functions with ~ (tilde).

If you’re interested in learning more about V8’s flags and how V8’s internals work in general, I strongly recommend looking through Vyacheslav Egorov’s excellent post on V8 internals, which summarizes the best resources available on this at the moment.

HIGH-RESOLUTION TIME AND NAVIGATION TIMING API

High Resolution Time (HRT) is a JavaScript interface providing the current time in sub-millisecond resolution that isn’t subject to system clock skews or user adjustments. Think of it as a way to measure more precisely than we’ve previously had with new Date and Date.now(). This is helpful when we’re writing performance benchmarks.

HRT is currently available in Chrome (stable) as window.performance.webkitNow(), but the prefix is dropped in Chrome Canary, making it available via window.performance.now(). Paul Irish has written more about HRT in a post on HTML5Rocks.

So, we now know the current time, but what if we wanted an API for accurately measuring performance on the web?

Well, one is now also available in the Navigation Timing API. This API provides a simple way to get accurate and detailed time measurements that are recorded while a webpage is loaded and presented to the user. Timing information is exposed via window.performance.timing, which you can simply use in the console:

Looking at the data above, we can extract some very useful information. For example, network latency is responseEnd-fetchStart, the time taken for a page load once it’s been received from the server is loadEventEnd-responseEnd and the time taken to process between navigation and page load is loadEventEnd-navigationStart.

As you can see above, a perfomance.memory property is also available that gives access to JavaScript memory usage data such as the total heap size.

For more details on the Navigation Timing API, read Sam Dutton’s great article Measuring Page Load Speed With Navigation Timing.

6/7

Page 27: Appliness #9 – December 2012

ABOUT THIS ARTICLE

Addy Osmani is a Developer Programs Engineer on the Chrome team at Google. A passionate JavaScript developer, he has written open-source books like ‘Learning JavaScript Design Patterns’ and ‘Develop-ing Backbone Applications’, having also contributed to open-source projects like Modernizr and jQuery. He is currently working on ‘Yeoman’ - an opinion-ated workflow for building beautiful applications. http://addyosmani.com/blog/

@addyosmani

MORE ARTICLES FROM...

http://www.smashingmagazine.com/

ABOUT:MEMORY AND ABOUT:TRACING

about:tracing in Chrome offers an intimate view of the browser’s performance, recording all of Chrome’s activities across every thread, tab and process.

What’s really useful about this tool is that it allows you to capture profiling data about what Chrome is doing under the hood, so you can properly adjust your JavaScript execution, or optimize your asset loading. Lilli Thompson has an excellent write-up for games developers on using about:tracing to profile WebGL games. The write-up is also useful for general JavaScripters. Navigating to about:memory in Chrome is also useful as it shows the exact amount of memory being used by each tab, which is helpful for tracking down potential leaks.

CONCLUSION

As we’ve seen, there are many hidden performance gotchas in the world of JavaScript engines, and no silver bullet available to improve performance. It’s only when you combine a number of optimizations in a (real-world) testing environment that you can realize the largest performance gains. But even then, understanding how engines interpret and optimize your code can give you insights to help tweak your applications.

Measure It. Understand it. Fix it. Rinse and repeat.

Remember to care about optimization, but stop short of opting for micro-optimization at the cost of convenience. For example, some developers opt for .forEach and Object.keys over for and for in loops, even though they’re slower, for the convenience of being able to scope. Do make sanity calls on what optimizations your application absolutely needs and which ones it could live without. Also, be aware that although JavaScript engines continue to get faster, the next real bottleneck is the DOM. Reflows and repaints are just as important to minimize, so remember to only touch the DOM if it’s absolutely required. And do care about networking. HTTP requests are precious, especially on mobile, and you should be using HTTP caching to reduce the size of assets.

Keeping all of these in mind will ensure that you get the most out of the information from this post. I hope you found it helpful!

Page 28: Appliness #9 – December 2012

appliness( DON’T WORRY, BE APPLI

by Kianosh Pourian

WHY I CHOSE SASS KIANOSH DESCRIBES HIS HISTORY WITH SASS AND DIVES IN TO SASS TO SHOW WHY HE PREFERS SASS AS A CSS PRE-PROCESSOR.

Learning to appreciate the advantages of using pre-processors like Sass CSS in my work flow was not very hard for me. At times the challenge has been convincing others of the advantages of Sass and at times it can be divisive. A pre-processor is a simple tool that will provide some of the following advantages:

•Smooth some of the harsh edges and create code frameworks i.e. consistent code patterns

•Extends the current process further by adding needed and missing features

A pre-processor like Sass does both.

My introduction to Sass was in 2009 during an interview for a job. During this interview, the interviewer asked me if I knew of Sass. I did not. However after the interview, I googled it and was introduced to the world of sass-lang.com. After the 5 minutes that it took to install it on my Mac (Sorry PC users, it might take 10 minutes for you), I was up and running. I played around with all its features and before I knew it, I was hooked.

In future projects, I was introduced to other CSS specific pre-processors like LESS, Stylus, and Closure Stylesheets. There has been certain feature sets that have made me gravitate back to Sass. Here are some of those features (I have used some code example from a real project) :

THE BASICS

All CSS pre-processors are built on the DRY (Don’t Repeat Yourself) prin-ciple. On that basis they all have the following features:

•Variables

Page 29: Appliness #9 – December 2012

•Import

•Mixins

•Functions

•Selector Inheritance

Variables, Import, and Mixins are basic features that were my first foray into Sass and all by themselves have added quite a punch in this application.

CSS is a great language allowing designers and developers to improve the presentation layer. But until the introduction of pre-processors like Sass it has been a static language that uses its cascading feature to dynamically override styles and apply them to the presentation. With the introduction of Sass, DRY principles were added to CSS and therefore extending its features.

So let’s dive into some code and learn about Sass. The following is an example of a simple CSS. On one of the projects that I have been working on, I needed to create a header for sections of the site. This header will have a linear gradient background and white colored text.

/*This is a variable for the primary color of the side*/

$primary: #00096E;

/*primary grey color to be used throughout the site*/

$greyColor: #E0E0E0;

/*This is an example of a mixin that will create a linear gradient. The advantages of using this is

that we do not have to write the multiple vendor prefixed CSS repeatedly. And code maintenance is easier.*/

//this mixin will create a linear-gradient. The parameters passed here are://$pos: position of the gradient which defaults to top but can take bottom, left, or right//$G1-G10: these allow for 10 color stops values, color and length/percentage//$fallback: this is the fallback color that will be used for older browsers, if this parameter//is not provided then the first color stop is used.@mixin linear-gradient($pos, $G1, $G2: false, $G3: false, $G4: false, $G5: false, $G6: false, $G7: false, $G8: false, $G9: false, $G10: false, $fallback: false) {

// Detect what type of value exists in $pos $pos-type: type-of(nth($pos, 1));

// If $pos is missing from mixin, reassign vars and add default position @if ($pos-type == color) or (nth($pos, 1) == “transparent”) { $G10: $G9; $G9: $G8; $G8: $G7; $G7: $G6; $G6: $G5; $G5: $G4; $G4: $G3; $G3: $G2; $G2: $G1; $G1: $pos; $pos: top; // Default position }

2/7

Page 30: Appliness #9 – December 2012

$pos: unquote($pos);

$full: $G1; @each $g in $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10 { @if $g != false { $full: $full + ‘,’ + $g; } }

$full: unquote($full);

//If using COMPASS uncomment the line below and remove line 82 - 89 //$full: compact($G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10);

// Set $G1 as the default fallback color $fallback-color: nth($G1, 1);

// If $fallback is a color use that color as the fallback color @if type-of($fallback) == color { $fallback-color: $fallback; }

background: $fallback-color; background: webkit-gradient(linear, $full); background: -webkit-linear-gradient($pos, $full); background: -moz-linear-gradient($pos, $full); background: -ms-linear-gradient($pos, $full); background: -o-linear-gradient($full); background: unquote(“linear-gradient(#{$full})”);};

The above mixin is courtesy of Thoughbot’s Bourbon mix which has quite an extensive collection of Sass mixins and functions.

FUNCTIONS

Sass comes with several built in functions. These are functions that are commonly used and they fall in the following categories:

•RGB functions

•HSL function

•Opacity functions

•Other Color functions

•String functions

•Number functions

•List functions

•Introspection functions

•Miscellaneous functions 3/7

Page 31: Appliness #9 – December 2012

Aside from the built-in functions, custom functions can also be created.

.main-header {

@include linear-gradient(top, $primary, lighten($primary, 20%)); color: white; display: inline-block; font-size: rfs(36); margin-left: 20px;

}

In this example, we are taking advantage of built-in color functions by passing the primary color and a 20% percent lighten primary color to our linear gradient mixin. We also are using a custom function that we have created to calculate the pixel font size in em, for a more responsive approach. Here is the detail of that function:

// ==|===Responsive Font Size calculator====================// Function that will calculate the responsive font size// return the em value to be used.// =========================================================*/@function responsiveFontSize($fontSize: $defaultBrowserSize, $isIE: false) { @if $isIE { @return (($fontSize/$defaultBrowserSize) - 0.02) + em; } @else { @return ($fontSize/$defaultBrowserSize) + em; }}@function rfs($fontSize: $defaultBrowserSize, $isIE: false) { @return responsiveFontSize($fontSize, $isIE);}

For more information on functions, refer to the Sass documentation.

SELECTOR INHERITANCE

This feature is one of the best features of Sass and one of the least used. This feature allows the user to think of the CSS and its features holistically and ensure the proper relationship among all the presenta-tion elements.

For example there are times that one class will encompass most of the styles needed however there will an addition of other classes that will include not the styles of the more general class but also some of its own. For example, in our code above we have a ‘main-header’ class. Now we want to create sub headers:

.main-header {

@include linear-gradient(top, $primary, lighten($primary, 20%)); color: white; display: inline-block; font-size: rfs(36); margin-left: 20px;

} 4/7

Page 32: Appliness #9 – December 2012

.sub-header { @extend .main-header; @include linear-gradient(top, $secondary, lighten($secondary, 15%)); font-size: rfs(24);}

In this example, we inherited all the styles from ‘main-header’ and over-wrote the linear gradient with a different color and reduced the size of our font. And the output will look something like this:

.main-header, .sub-header { background: #00096e; background: webkit-gradient(linear, #00096e,#0011d4); background: -webkit-linear-gradient(top, #00096e,#0011d4); background: -moz-linear-gradient(top, #00096e,#0011d4); background: -ms-linear-gradient(top, #00096e,#0011d4); background: -o-linear-gradient(#00096e,#0011d4); background: linear-gradient(#00096e,#0011d4); color: white; display: inline-block; font-size: 2.25em; margin-left: 20px;

}

.sub-header { background: #cfc35d; background: webkit-gradient(linear, #cfc35d,#e0d998); background: -webkit-linear-gradient(top, #cfc35d,#e0d998); background: -moz-linear-gradient(top, #cfc35d,#e0d998); background: -ms-linear-gradient(top, #cfc35d,#e0d998); background: -o-linear-gradient(#cfc35d,#e0d998); background: linear-gradient(#cfc35d,#e0d998); font-size: 1.5em;}

For a more comprehensive example of selector inheritance read this article by Thomas Reynolds.

PLACEHOLDER SELECTORS

Placeholder selectors follow the guideline of selector inheritance with one major improvement, they are silent until needed. A placeholder selector is a series of styles that are created for when there is situation where it is needed. If it is not extended, it will not be compiled to the final css output. If it is extended then the resulted styles will be in the output but the placeholder selector will not be in the compiled css. If we follow the example above, then the code will look like this:

%header-setup{ color: white; display: inline-block; margin-left: 20px;}

5/7

Page 33: Appliness #9 – December 2012

.main-header { @extend %header-setup; @include linear-gradient(top, $primary, lighten($primary, 20%)); font-size: rfs(36);}

.sub-header { @extend %header-setup; @include linear-gradient(top, $secondary, lighten($secondary, 15%)); font-size: rfs(24);}

We placed the portion of the styles common to both classes in a placeholder selector and named it head-er-setup. The output of the code looks like this:

.main-header, .sub-header { color: white; display: inline-block; margin-left: 20px;

}

.main-header { background: #00096e; background: webkit-gradient(linear, #00096e,#0011d4); background: -webkit-linear-gradient(top, #00096e,#0011d4); background: -moz-linear-gradient(top, #00096e,#0011d4); background: -ms-linear-gradient(top, #00096e,#0011d4); background: -o-linear-gradient(#00096e,#0011d4); background: linear-gradient(#00096e,#0011d4); font-size: 2.25em;

}

.sub-header { background: #cfc35d; background: webkit-gradient(linear, #cfc35d,#e0d998); background: -webkit-linear-gradient(top, #cfc35d,#e0d998); background: -moz-linear-gradient(top, #cfc35d,#e0d998); background: -ms-linear-gradient(top, #cfc35d,#e0d998); background: -o-linear-gradient(#cfc35d,#e0d998); background: linear-gradient(#cfc35d,#e0d998); font-size: 1.5em;

}

6/7

Page 34: Appliness #9 – December 2012

ABOUT THIS ARTICLE

I am a native born Iranian and reside in Boston Mas-sachusetts. Husband to a lovely New Englander and father to two lovely girls. In my spare time, I am an enthusiast in all things involving UI develop-ment and am lucky enough to be working in that field for clients like VMWare, MIT, and Novartis. http://innovatorylife.com/

@kianoshp

ONLINE RESOURCES

SASShttp://sass-lang.com/

SASS Documentationhttp://sass-lang.com/docs/yardoc/Sass/Script/Functions.html

DRY Principlehttp://en.wikipedia.org/wiki/Don’t_repeat_yourself

OBJECT ORIENTED CSS (OOCSS)

Sass allows for a better framework for the implementation of OOCSS. If you are unfamiliar with OOCSS, Nicole Sullivan‘s answer to writing a well structured, efficient and performant CSS; here are a few resourc-es:

•How to write a well structured CSS

•http://oocss.org/

•https://github.com/stubbornella/oocss/wiki

•http://coding.smashingmagazine.com/2011/12/12/an-introduction-to-object-oriented-css-oocss/

Combining Sass and OOCSS principles make for a great way to write CSS. Here are some great articles in this regard:

•http://ianstormtaylor.com/oocss-plus-sass-is-the-best-way-to-css/

•http://takazudo.github.com/presentation-oocss-sass/#/

•http://memerocket.com/2009/03/28/oocss-sass-fewer-classes-on-your-elements/

CONCLUSION

Sass is a great that will enhance and improve upon CSS. If you have any reservations about using Sass, just experiment with it especially with the SCSS extension which allows you to use regular CSS in their along side with all the features of Sass. Cheers.

Page 35: Appliness #9 – December 2012

appliness( DON’T WORRY, BE APPLI

by Sangmin, Shim

COLLIE TUTORIALSCHECKOUT THIS GREAT TUTORIAL ON THE COLLIE JAVASCRIPT LIBRARY TO LEARN MORE ABOUT MAK-ING ANIMATION AND GAMES OPTIMIZED FOR THE MOBILE PLATFORM.

#1 Web in the old days was invented for the purpose of delivering information on static pages. However with the advent of HTML5 and improved JavaScript performance, various attempts have been made on web browser.

Animation and games are no exceptions. Efforts to create animations and games using HTML5 canvas and CSS3 have been made numerously, along with many libraries being introduced for supporting such trial.

In response to vitalizing mobile market, many attempts have been made on desk tops. On the mobile platform, however, it is difficult to create optimum animations and games via generally known method, since the lineup of mobile device is too massive, not to mention the fragmentation issue of OS.

This guide is for getting to know JavaScript Library Collie which facilitates animation and games creation optimized for mobile platform. Guided by this tutorial, let’s create codes for creating simple animations.

INTRODUCTION

Page 36: Appliness #9 – December 2012

#2The control flow bindings introduced in Knockout 2.0 are really just simple wrappers to the template Collie is a JavaScript library for making animation and games optimized for mobile platform. LGPL v2.1 which is an open source license has been adopted and it is downloadable on http://jindo.dev.naver.com/collie/

Living up to its reputation as ‘the most optimized JS library for mobile,’ Collie was introduced to the world through passing various tests on more than 18 mobile devices and many operating systems. Col-lie operates differently on each device by selecting respective rendering method based on its test result. The testing result is open for all on below website.

Figure 2‑1 Performance Test Page per Mobile Device and OS

Collie uses HTML5 Canvas or CSS3 based on the situation for its rendering. The interface is identical in spite of different operating method. Thus, it enables the users to use only one interface without contem-plating on which rendering to operate since it automatically results in outputs optimized for various de-vices.

Although there are some restrictions and bugs detected per device and OS, Collie lets you to engage in development without having to worry about those matters. On top of that Collie is ever more evolving to promise a quality performance on mobile platform by applying various options and algorithms.

With its superb usability, learning to utilize a simple API will ensure you to create animations and games with ease. First, let us get the glimpse of what Collie is by creating a simple demo.

INTRODUCING COLLIE

2/14

Page 37: Appliness #9 – December 2012

#3Let us complete simple exercise of displaying Collie logo in the middle of the screen to familiarize our-selves with basic structure before actually working on the demo. If you make a code following below de-scription, you will be able to see Collie log rotating constantly in the center of the screen

CREATING MARK-UP

First, load Collie script to a page as described below.

<!doctype html><html><head><meta charset=”utf-8” /><meta name=”viewport” content=”width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no” /></head><body><div id=”container”></div><script type=”text/javascript” src=”http://jindo.dev.naver.com/collie/deploy/collie.min.js”></script><script type=”text/javascript”> // Create code here.</script></body></html>

There is no need to use other Scripts for writing Collie script. The size wouldn’t be too much of a burden since it is around 20kb when g-zipped. It should be inserted within head tag or before using Collie.

Although Collie script is provided on Deploy folder within official Collie website, for a more stable ser-vice, I would like to recommend you to download it from official website.

<meta name=”viewport” content=”width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no” />

Above meta tag is required information for viewing pages as it is, on Mobile platform. Please refer to (http://developer.apple.com/library/ios/#documentation/AppleApplications/Reference/SafariWebCon-tent/UsingtheViewport/UsingtheViewport.html) for further details on how to set viewport.

CREATING LAYER

Before creating logo object, layer for holding display object should be created. Layer is capable of hold-ing various display objects and a single canvas belongs to a single layer. The layer will be created as fol-lows.

var layer = new collie.Layer({ width: 320, height: 480});

Option is entered in the first factor of the creator in layer as an object. Above option is for creating lay-er corresponding to a mobile display with 320 width and 480 height. Please refer to an API document (http://jindo.dev.naver.com/collie/doc/collie.Layer.html) for further information.

CREATING A SIMPLE SAMPLE

3/14

Page 38: Appliness #9 – December 2012

LOADING IMAGE USING IMAGEMANAGER

Generally images used in animation or games are loaded asynchronously since the volume and number is considerable. Thus, Collie asynchronously manages its image resources as well using ImageManager. You may load images using add method in ImageManager as described below.

collie.ImageManager.add({ logo: “http://jindo.dev.naver.com/collie/img/small/logo.png”});// Create display object. Although image has yet to be loaded, you may use the logo.

Although ImageManager loads images asynchronously, users can create display objects using the images without checking the loading result. Once display object is created and image loading gets completed, ImageManager allocates loaded image to display object. However, if you don’t wish empty display object to be in display, you can create object after all images are loaded.

collie.ImageManager.add({ logo: “http://jindo.dev.naver.com/collie/img/small/logo.png”}, function () { // Create display object after all images are loaded});

Please refer to API document (http://jindo.dev.naver.com/collie/doc/collie.ImageManager.html) for fur-ther information.

CREATING DISPLAY OBJECT

In order to display loaded image to the screen, display object needs to be created. There are various kinds of display objects including Circle for marking circle from DisplayObject and Text for indicating Text. Cre-ate display object using MovableObject capable of using veolocity attribute since the logo needs to be constantly rotating.

var logo = new collie.MovableObject({ x: “center”, y: “center”, backgroundImage: “logo”, velocityRotate: 50}).addTo(layer);

While creating display object, you can add corresponding object to layer using addTo method. Display object will only be displayed on the screen when it is added to layer or parent display object.

Display object, likewise, will be entered with option as the first factor. You may also type character strings for x and y same as the center and coordinate in the unit of pixel can be entered in. Input image resource key loaded in ImageManager beforehand into the backgroundImage. Display object will be set befitting the background image size unless width and height value is specified.

VelocityRotate is an exclusive option for MovableObject which refers to the rotation angle per second. For instance, set as 50, the object will rotate 50 degrees for every second. Moving velocity can also be designated using velocityX and velocityY. Please refer to API document (http://jindo.dev.naver.com/col-lie/doc/collie.MovableObject.html) for further information.

4/14

Page 39: Appliness #9 – December 2012

PREPARING RENDERER

Display object has been created and added to layer. Add the prepared layer to Renderer and execute Renderer to view the object on actual screen.

collie.Renderer.addLayer(layer);collie.Renderer.load(document.getElementById(“container”));collie.Renderer.start();

First of all, add the prepared layer onto Renderer using addLayer method. And use load method to ini-tialize Collie on DOM object. DOM object with its ID of a container, has been added as described below during mark-up creation phase.

<div id=”container”></div>

Lastly, run Renderer using start method. As the first factor, Start method supports time frame in the unit of millisecond that is displayed on the screen. You may also add fps at the end for inputting in the unit of FPS through adding fps at the end. The default value is “60fps.” In normal mobile setting it is the most effective to run with “30fps.”

collie.Renderer.start(“30fps”);

#3The following is the code created so far.

<!doctype html><html><head><meta charset=”utf-8”><meta name=”viewport” content=”width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no” /></head><body><div id=”container”></div><script type=”text/javascript” src=”http://jindo.dev.naver.com/collie/deploy/collie.min.js”></script><script type=”text/javascript”>var layer = new collie.Layer({ width: 320, height: 480}); collie.ImageManager.add({ logo: “http://jindo.dev.naver.com/collie/img/small/logo.png”}); var logo = new collie.MovableObject({ x: “center”, y: “center”, velocityRotate: 50, backgroundImage: “logo”

SUMMARY

5/14

Page 40: Appliness #9 – December 2012

}).addTo(layer); collie.Renderer.addLayer(layer);collie.Renderer.load(document.getElementById(“container”));collie.Renderer.start();</script></body></html>

Use above coding to create an object displaying constantly rotating image on the screen. You may also find above coding in http://jsbin.com/iwakuj/2/

Figure 3‑1: Constantly rotating logo image

Additionally, the idea of automatically processing each binding independently is being explored for a fu-ture version of Knockout.

#4So far, we have looked into how to use Collie by making simple demonstrations. Now moving on from a rather boring static logo, let’s create a moving rabbit with Sprite.

PREPARING IMAGE AND OBJECT

Sprite expresses continuous scene into a single cut image as shown below.

Image 4‑1: Sprite image of walking rabbit

CREATING MOTIONS USING SPRITE

6/14

Page 41: Appliness #9 – December 2012

When creating display object with Sprite, the size of a single screen shall be based on width and height option.

collie.ImageManager.add({ rabbit: “http://jindo.dev.naver.com/collie/img/small/yame_walk.png”});var rabbit = new collie.DisplayObject({ x: “center”, y: “center”, width: 129.4, height: 165, backgroundImage: “rabbit”}).addTo(layer);

Image 4‑2: Display object which only shows the first frame of Sprite image

ANIMATION

Followed by above stage, execute Renderer to find an immovable rabbit on the screen. To infuse a life into this rabbit, let’s define animation. Collie supports various animations such as delay, repeat and tran-sition. Here, cycle animation is used for Sprite.

collie.Timer.cycle(rabbit, “18fps”, { from: 0, to: 8, loop: 0});

Animation can be created using collie.Timer. Input related display object or callback function in the first factor and time (millisecond unit) in the second. For more convenience, add fps at the end for Cycle ani-mation. When set as “18fps” for instance, at a speed of 18 movements per second, the frame changes 9 times from 0 to 8.

The third factor is for inputting animation option. Please refer to API document (http://jindo.dev.naver.com/collie/doc/collie.AnimationCycle.html) for further information.

The following is the organized coding.

<!doctype html><html><head><meta charset=”utf-8”><meta name=”viewport” content=”width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no” /></head>

7/14

Page 42: Appliness #9 – December 2012

<body><div id=”container”></div><script type=”text/javascript” src=”http://jindo.dev.naver.com/collie/deploy/collie.min.js”></script><script type=”text/javascript”>var layer = new collie.Layer({ width: 320, height: 480}); collie.ImageManager.add ({ rabbit: “http://jindo.dev.naver.com/collie/img/small/yame_walk.png”}); var rabbit = new collie.DisplayObject({ x: “center”, y: “center”, width: 129.4, height: 165, backgroundImage: “rabbit”}).addTo(layer); collie.Timer.cycle(rabbit, “18fps”, { from: 0, to: 8, loop: 0}); collie.Renderer.addLayer(layer);collie.Renderer.load(document.getElementById(“container”));collie.Renderer.start();</script></body></html>

Enter above code to find a walking rabbit. You will also find above code in http://jsbin.com/usaqih/1/

8/14

Page 43: Appliness #9 – December 2012

#5It might be very boring, if the rabbit were to be the only movable object. Now, let’s make a movable ground that proceeds according to rabbit’s walk.

PREPARING IMAGE AND OBJECT

To make a constantly moving ground, you need to prepare image that is more than double the size of what is displayed on the screen. Without having to prepare a repeating image separately, create required object using backgroundRepeat attribute of display object as shown below.

collie.ImageManager.add({ ground: “http://jindo.dev.naver.com/collie/img/large/ground.png”});var ground = new collie.MovableObject({ x: 0, width: 320 * 2, height: 88, velocityX: -50, backgroundImage: “ground”, backgroundRepeat: “repeat-x”}).bottom(0).addTo(layer);

Since the ground needs to be proceeding towards the opposite direction of rabbit, you need to use Mov-ableObject and input velocity value using. To make the object seem as if it is moving continuously, the ground needs to return to the original position every time each screen passes by. Therefore, rangeX and positionRepeat option need to be added to the following display object.

var ground = new collie.MovableObject({ x: 0, width: 320 * 2, height: 88, velocityX: -50, backgroundImage: “ground”, backgroundRepeat: “repeat-x”, rangeX: [-320, 0], positionRepeat: true}).bottom(0).addTo(layer);

RangeX refer to the scope of x-coordinate allowed for object to move and positionRepeat is for deciding whether to move to the opposite end when object reached one end.

CREATING CONTINUOUSLY MOVING BACKGROUND

9/14

Page 44: Appliness #9 – December 2012

#6 To give a more vivid touch, you would want to make the rabbit jump up by clicking mouse or touching the screen. Such function can be materialized by using object events.

ADDING EVENT TO OBJECT

Event can be added by using attach method on rabbit object. Using click event, the object will respond to both touch and click since Collie supports mobile and desktop events at the same time.

rabbit.attach({ click: function (e) { // Perform specific motion }});

DEFINING ANIMATION

Define a parabolic motion to make the object seem like jumping. Use transition animation and animation queue as detailed below for parabolic motion.

var currentY = rabbit.get(“y”);rabbit.attach({ click: function (e) { collie.Timer.queue(). transition(rabbit, 400, { to: currentY - 100, effect: collie.Effect.easeOut, set: “y” }). transition(rabbit, 400, { to: currentY, effect: collie.Effect.easeIn, set: “y” }); }});

Transition animation defines continuous motions by using various animation effects and animation queue is for combining multiple animations into a single one. Please refer to API document (http://jindo.dev.naver.com/collie/doc/collie.Effect.html) for more details on various animation effects that Collie supports.

#7You need to prepare a higher resolution image for devices supporting high-resolution display such as iPhone 4. Although there are various methods for meeting the high-resolution capacity, Collie enables you to support high-resolution display with ease. Now, let’s see how to support high-resolution display using Collie.

USING EVENT

HIGH-RESOLUTION DISPLAY

10/1

4

Page 45: Appliness #9 – December 2012

DELETING DEBUGGING CODE

Modify the following line when making a simple sample.

collie.Renderer.RETINA_DISPLAY = “auto”;

Default value for collie.Renderer.RETINA_DISPLAY is “false”. If you set this value as true or false, you will be able to create a high-resolution environment regardless of the type of device.

CONFIRMATION DURING IMAGE LOADING

When you opt for general resolution image during ordinary times and load high resolution image when it comes to catering to high-resolution display, Collie automatically calculates the value and displays ac-cordingly on the screen. It is not easy to apply such condition to all objects; however on Collie, all you need to do is to use isRetinaDisplay method of Renderer and load images suitable for each resolution for Retina display.

var folder = collie.Renderer.isRetinaDisplay() ? “large” : “small”;collie.ImageManager.add({ rabbit: “http://jindo.dev.naver.com/collie/img/” + folder + “/yame_walk.png”, ground: “http://jindo.dev.naver.com/collie/img/” + folder + “/ground.png”});

Image 7‑1: High‑resolution image (left) specially made for Retina Display and ordinary image (right) when viewed on Retina Display

#8So far, we have looked into methods for operating Retina Display support mode using collie.Renderer.RETINA_DISPLAY value. Now, we are going to look into additional functions that are also beneficial.

RENDERING MODE

Desktop provides a more convenient developing environment than mobile. Collie provides multiple vari-ables for selecting rendering mode (HTML5 canvas and Dom rendering) to better cater to each develop-ment circumstance.

collie.Renderer.DEBUG_RENDERING_MODE = “dom”;

Above code shall be defined before using Collie. Default value for collie.Renderer.DEBUG_RENDERING_MODE is “auto” and you may view specific mode by setting “canvas” or “dom”.

FPS CONSOLE

FPS represents the performance of animation and game. Collie provides FPSConsole for checking FPS on screen on demand.

DEBUGGING

11/1

4

Page 46: Appliness #9 – December 2012

var fpsConsole = new collie.FPSConsole();fpsConsole.load();

Tool script is required for using FPSConsole as specified above. Tool script can be called for use as speci-fied below.

<script type=”text/javascript” src=”http://jindo.dev.naver.com/collie/deploy/collie.tool.min.js”></script>

#9Below is the code created so far. Correctly following below code will lead to a walking rabbit and a jump-ing one at a click (touch) of the rabbit on the screen.

<!doctype html><html><head><meta charset=”utf-8”><meta name=”viewport” content=”width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no” /></head><body><div id=”container”></div><script type=”text/javascript” src=”http://jindo.dev.naver.com/collie/deploy/collie.min.js”></script><script type=”text/javascript”>collie.Renderer.RETINA_DISPLAY = “auto”;var folder = collie.Renderer.isRetinaDisplay() ? “large” : “small”;collie.ImageManager.add({ rabbit: “http://jindo.dev.naver.com/collie/img/” + folder + “/yame_walk.png”, ground: “http://jindo.dev.naver.com/collie/img/” + folder + “/ground.png”}); var layer = new collie.Layer({ width: 320, height: 480});var rabbit = new collie.DisplayObject({ x: “center”, width: 129.4, height: 165, zIndex: 2, backgroundImage: “rabbit”}).bottom(50).addTo(layer);var currentY = rabbit.get(“y”);rabbit.attach({ click: function (e) { collie.Timer.queue(). transition(rabbit, 400, { to: currentY - 100,

SUMMARY

12/1

4

Page 47: Appliness #9 – December 2012

effect: collie.Effect.easeOut, set: “y” }). transition(rabbit, 400, { to: currentY, effect: collie.Effect.easeIn, set: “y” }); }});collie.Timer.cycle(rabbit, “18fps”, { from: 0, to: 8, loop: 0});var ground = new collie.MovableObject({ x: 0, width: 320 * 2, height: 88, velocityX: -200, backgroundImage: “ground”, backgroundRepeat: “repeat-x”, rangeX: [-320, 0], positionRepeat: true}).bottom(0).addTo(layer);collie.Renderer.addLayer(layer);collie.Renderer.load(document.getElementById(“container”));collie.Renderer.start();</script></body></html>

You will find above code in http://jsbin.com/oyopeq/2/

13/1

4

Page 48: Appliness #9 – December 2012

ABOUT THIS ARTICLE

He is a Senior JavaScript developer working at NHN and the creator of the JavaScript animation library Col-lie. He is very interested in making JavaScript apps run faster and more smoothly. He has authored a book ti-tled “What You Need to Know about JavaScript’s Per-formance” and also writes mobile games using Collie. http://jindo.dev.naver.com/collie/

@davidshimjs

Collie Homehttp://jindo.dev.naver.com/collie/

Collie Downloadhttp://jindo.dev.naver.com/collie/index.html#download

Collie Documentationhttp://jindo.dev.naver.com/collie/index.html#documentation

ONLINE RESOURCES

#10Collie has not only focused on optimization for mobile platform but also on development convenience as well as the productivity. If you developing accordingly, you will be able to create the most optimal anima-tion which can tap into both DOM and Canvas depending on the circumstances, while supporting Retina display.

The ultimate goal of developing animation and game with Collie is to free the users from thinking about functional matters and ensure them to focus only on coding. In short, the user will be able to exert his/her energy in creation.

With Collie, you will be able to make animation/game of your own with ease!

SUMMARY

Page 49: Appliness #9 – December 2012

appliness( DON’T WORRY, BE APPLI

by Joe Zimmerman

PLUGGING INTO SOCKET.IO: ADVANCEDRECENTLY, WE LOOKED AT THE BASICS OF USING SOCKET.IO. AS WE WENT THROUGH THAT, WE DISCOVERED THAT SOCKET.IO AFFORDS US A VERY SIM-PLE API BASED ENTIRELY OFF OF SENDING AND RECEIVING MESSAGES AND BEING NOTIFIED OF THOSE MESSAGES THROUGH EVENTS. WELL, THERE’S MORE TO SOCKET.IO THAN THAT. IT HAS SEVERAL ADVANCED FEATURES THAT CAN COME IN VERY HANDY IN CERTAIN SITUATIONS.

BUILT-IN EVENTS

This isn’t exactly an advanced feature. I just didn’t have the time to include it in the previous post. Any-way, you saw that both the client and server side had a means of doing something once the connection was made:

// Server Sideio.listen(80);io.sockets.on(‘connection’, function(socket){ . . .}); // Client Sidesocket = io.connect(‘http://localhost/’);socket.on(‘connect’, function() { . . .});

Page 50: Appliness #9 – December 2012

On the back end, it is required that you react to this, otherwise you won’t be able to do anything with the connection. On the front end, though, this isn’t required, but it is usually helpful. In addition, both sides can also react to a disconnection. The code below applies to both front and back end.

socket.on(“disconnect”, function() { // Let the users know something bad happened or log the disconnect});

Don’t bother trying to reconnect in there, at least not right away. Socket.IO will try to reconnect on its own a certain number of times and it spaces out each reconnection attempt a little wider each time. But, it does give up after a while, so you might want to throw some setTimeouts in there to continue trying to reconnect later if you want. Oh, and by the way, you can disconnect on purpose, which doesn’t cause the client to try connecting again, but should still fire the “disconnect” event:

// Client Sidesocket.disconnect();

There is also a “message” event, which is used to make Socket.IO conform more closely to the Web-Socket semantics. This way, all messages are received and dealt with within this single callback and you don’t need to make up names for the messages. When using this, you also use send rather than emit to send messages.

// Server Sideio.listen(80);io.sockets.on(‘connection’, function (socket) { socket.on(‘message’, function (message) { console.log(message); socket.send(‘message was received’); });}); // Client Sidesocket = io.connect(‘http://localhost/’);socket.on(‘connect’, function() { . . .});socket.on(‘message’, function (message) { console.log(message); socket.send(‘message was received’);});

ACKNOWLEDGEMENT

Sometimes, you want to have the system set up to have a response from the server any time the server receives your messages. You can do this by sending functions to the server, which the server will then call “directly” and pass some data in to it.

// Server Sidesocket.on(“getMessage”, function(func) { func(“The Message”);}); // Client Sidesocket.emit(“getMessage”, function(message) { 2/

6

Page 51: Appliness #9 – December 2012

console.log(message);});

When this is run, “The Message” will be posted in the client’s console. This might seem a bit like magic, but really it’s just a clever use of a proxy. The function itself isn’t actually being called. Rather a different function is being called in its place, which sends the data back to the client and has the actual function called there with the data that was sent. It’s a very nice system to ensure you receive acknowledgement of when the server receives your request. You could, of course, just rewrite the code like this and achieve the exact same effect, though.

// Server Sidesocket.on(“getMessage”, function(func) { socket.emit(“theMessage”, “The Message”);}); // Client Sidesocket.emit(“getMessage”);socket.on(“theMessage”, function(message) { console.log(message);});

It’s a little more code and it isn’t entirely clear from the client’s perspective that “theMessage” will be sent back immediately when “getMessage” is received, but it still works just as well.

STORING CLIENT DATA

Essentially Socket.IO has a special type of session storage that you can use to store information about each connected socket client. It’s also really simple to use, just like pretty everything else about this li-brary.

// Server Sidesocket.on(‘set nickname’, function (name) { socket.set(‘nickname’, name, function () { socket.emit(‘ready’); });}); socket.on(‘msg’, function () { socket.get(‘nickname’, function (err, name) { console.log(‘Chat message by ‘, name); });}); // Client Sidesocket.emit(‘set nickname’, user.nickname); socket.on(‘ready’, function () { console.log(‘Connected !’); socket.emit(‘msg’, message);});

3/6

Page 52: Appliness #9 – December 2012

As you can see, it works well for storing a user’s nickname so that everyone in a chat can know who is sending the messages. Simply use socket.set and socket.get. Make sure you notice that they are asynchronous, so they require a callback if you want to do anything immediately after the value is saved or retrieved.

BROADCASTING

So you want to be on television? Sorry, wrong kind of broadcasting. By broadcasting, I mean sending a message to everyone who is connected to the server. We already talked about this in the previous post, where I said that on the server side you could use io.sockets.emit rather than socket.emit to send a message to every client that is connected.

socket.on(‘chat message’, function(msg) { io.sockets.emit(‘message’, msg);});

There is potentially a problem with this setup, though: it sends the message to the original client too. The client who sent “chat message” probably doesn’t need to receive it back. To get around this, there is a mechanism that allows you to send a message to everyone except the original client. Just use socket.broadcast.emit. The above code can now be written like this:

socket.on(‘chat message’, function(msg) { socket.broadcast.emit(‘message’, msg);});

SEGMENTING USERS: ROOMS AND NAMESPACES

Sometimes you don’t want all of the users lumped up together in the same pool. You might want to send messages to some clients and not others. For this we have two different ways of segmenting users: Rooms and Namespaces.

ROOMS

Users can be assigned to different rooms and then can be contacted when broadcasts are made to that room. First off, let’s learn how clients can be assigned to and removed from rooms. All of this is done on the server side. The client has no real power in controlling which rooms it is assigned to, except to send messages normally that the server responds to by changing whether you are in a room or not.

// Server Sidesocket.on(‘addToRoom’, function(roomName) { socket.join(roomName);}); socket.on(‘removeFromRoom’, function(roomName) { socket.leave(roomName);});

Simply use socket.join and socket.leave to join and leave rooms, respectively. I’m pretty sure (though I haven’t tried it. You should try it if you’re interested) that a socket can join multiple rooms at once. Now that you’re assigned to a room, whenever someone broadcasts to the entire room, you will be notified. Here’s how you broadcast to rooms: 4/

6

Page 53: Appliness #9 – December 2012

// Broadcast to everyone in a room, except yousocket.broadcast.to(“room name”).emit(“your message”); // Broadcast to everyone in a room, including youio.sockets.in(“room name”).emit(“your message”);

And that’s pretty much all there is to rooms!

NAMESPACES

Namespaces aren’t technically intended for segmenting your users. Rather, they are used to allow you to have multiple connections to multiple Socket.IO servers, but only require the use of a single Socket.IO server. In other words, a single server acts like multiple servers that you can connect to separately. While the intention is different, it does work to segregate users.

Let’s set up the server side to allow multiple connections:

var io = require(‘socket.io’).listen(80); var chat = io .of(‘/chat’) .on(‘connection’, function (socket) { // Send message to client like usual socket.emit(‘a message’, { that: ‘only’, socket: ‘will get’ }); // Broadcast message to everyone in this namespace chat.emit(‘a message’, { everyone: ‘in’, ‘/chat’: ‘will get’ }); }); var news = io .of(‘/news’); .on(‘connection’, function (socket) { socket.emit(‘item’, { news: ‘item’ }); });

As you can see, all you do is replace sockets with of(‘/namespace’) when you start the on(‘connection’, function(){}) call. This creates a segment of connections that you can keep separate from other connections. As you can see, this setup allows you to broadcast to everyone in this namespace too.

Now we need the clients to connect to them separately. Simply just create separate connections to each of the namespaces and you’re all set.

var chat = io.connect(‘http://localhost/chat’), news = io.connect(‘http://localhost/news’); chat.on(‘connect’, function () { chat.emit(‘connectedToChat’);}); news.on(‘news’, function () { news.emit(‘ connectedToNews’);});

Just add the namespace to the end of the normal URL and you’ll connect to the Socket.IO server with that namespace. You can treat chat or news exactly the same way you used to treat socket in the sin-gle-connection scenarios.

5/6

Page 54: Appliness #9 – December 2012

ABOUT THIS ARTICLE

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

@joezimjs

ONLINE RESOURCES

His bloghttp://www.joezimjs.com/

Adobe Developer portalhttp://www.adobe.com/devnet.html

Learning JS patterns by Addy Osmanihttp://addyosmani.com/resources/essentialjsdesignpatterns/book/

CONFIGURATION

Socket.IO has many configurable options, so they implemented a way to configure it. Here’s a quick look at how to do it.

io.configure(‘production’, function(){ io.enable(‘browser client etag’); io.set(‘log level’, 1); io.set(‘transports’, [‘websocket’, ‘flashsocket’, ‘xhr-polling’]);});

First, call io.configure sending in the environment you want the configuration to be set up for and a function. Inside the function, you can use io.enable (which just sets the option’s value to true), io.disable (which sets the value to false), and io.set (which sets the value to whatever the second argument is) to change all of the options available to Socket.IO.

If you want more information on changing the environments and which options are available, I recom-mend you take a look at the wiki page about configuring Socket.IO.

CONCLUSION

Socket.IO has proven itself to be a great replacement for straight WebSockets. It allows amazing custom-izability and a wonderfully simple API for enabling real-time 2-way communication between a server and client. It’s definitely worth taking a look at. God bless and happy coding!

Page 55: Appliness #9 – December 2012

appliness( DON’T WORRY, BE APPLI

by Raymond Camden

DYNAMICALLY LOADING A STYLE SHEET BASED ON WEATHER CONDITIONSSEE HOW RAY HAS FIGURED OUT HOW TO LOAD WEATHER DATA INTO DYNAMIC WEBSITE DESIGN.

I know what you’re thinking - thank God Ray is blogging about this topic. I can’t tell you the number of times clients have asked for a dynamic web site design based on the user’s current weather conditions. Well, today’s your lucky day! (Ok, all snark aside - I saw this asked on StackOverflow and thought it would be fun to build.)

In general, the process is relatively simple:

•Get the user’s location (simple!)

•Get the weather (mostly simple, depending on the API)

•Load a dynamic style sheet (simple!)

Of course, actually designing a style sheet that adequately conveys a particular weather condition is way beyond my stylistic chops. So if you pretend for a moment that I could actually design worth a damn, then hopefully the rest of the technical bits will be interesting. Ok, let’s do it.

Following the order of operations above, I began with a simple geolocation check/call.

document.addEventListener(“DOMContentLoaded”, init, false);

function init() { console.log(“init”);

//First, grab the users location if(geolocationSupported()) getLocation();}

function geolocationSupported() {

Page 56: Appliness #9 – December 2012

return navigator.geolocation;}

function getLocation() { console.log(“Requesting location”); //Notice - no error handler. Since this is just rainbows and unicorns, we can fail silently navigator.geolocation.getCurrentPosition(positionLoad);}

Hopefully none of this is too new to my readers. Due to the nature of this “feature”, I don’t have to worry about fallback of any sort. Users without geolocation support won’t get an error nor will the site “break”, they just won’t get the super fancy cool color scheme that matches their weather.

The second part involves getting the weather. I decided to use Weather Underground’s API for this. Yahoo has a nice API as well, but doesn’t support longitute/latitude weather lookups. (They do have a service to do this lookup for you, but I wanted a simpler API.) Weather Underground doesn’t support CORS, but does support JSON/P. I’m not using jQuery for this, but the code to do a JSON/P call is incredibly trivial.

function positionLoad(pos) { var long = pos.coords.longitude; var lat = pos.coords.latitude;

//Now that we’ve gotten our position, let’s get the weather //quick and dirty jsonp call var script = document.createElement(“script”); script.src = “http://api.wunderground.com/api/80955450a9ddb7f6/conditions/q/”+lat+”,”+long+”.json?callback=gotWeather”; document.getElementsByTagName(“head”)[0].appendChild(script);}

Ok, now for the fun part. The Weather Underground API returns a lot of data. All I care about is a key called “weather” that contains a general description. Examples: Mostly Cloudy, Partly Cloudy, Overcast. Unfortunately, they don’t bother to actually freaking document the unique values here. I decided to take a tour around the world to find various examples and apparently the entire world now is covered in cloud, much like in Star Trek 4. (Yes, the one with the whales.)

2/5

Page 57: Appliness #9 – December 2012

So for now, I took a few simple values, a few guesses, and just rolled with it. I figured it would make sense to condense some conditions into each other so I built it up as a simple Switch block.

function gotWeather(w) { //if we don’t have current_observation, we had an error, and again, we can ignore if(!w.current_observation) return;

var weatherType;

switch (w.current_observation.weather) { case “Mostly Cloudy”: case “Partly Cloudy”: case “Overcast”: weatherType = “cloudy”; break;

case “Rain”: weatherType = “rain”; break;

default: break; }

console.log(w.current_observation.weather,’weathertype is ‘+weatherType);

//Based on the general weather, load a style sheet if(weatherType) loadStyleSheet(weatherType);

}

The final part was rather simple. To load a dynamic style sheet into the browser you follow much the same pattern for doing JSON/P - simply create a new DOM item and inject it.

function loadStyleSheet(type) { var style = document.createElement(“link”); style.setAttribute(“rel”, “stylesheet”); style.type = “text/css”; style.href = “./css/”+type+”.css”; document.getElementsByTagName(“head”)[0].appendChild(style);}

Notice how each type of weather will match to a “something.css” in my css folder. To keep things simple, I added styles to the H1 and P tags. Here’s cloudy.css:

h1, p { color: gray;}

h1:after { font-style: italic; font-size: 0.6em; margin-left: 10px; content: “Cloudy”;} 3/

5

Page 58: Appliness #9 – December 2012

Note the use of the after pseudo-class. I use this to inject the actual weather description (or a similar one) after the h1 tag. Here’s an example based on my current location:

And since I have separate function, I was able to go into console and force it to the rainy version.

All in all, pretty simple. You can view the complete demo here: http://www.raymondcamden.com/dem-os/2012/nov/12/

I liked that - but - something nagged at me. Every time you load the page the code checks your location and gets the weather. Surely we could cache that, right? I built up a second version that makes use of sessionStorage. I update the setup code first:

function init() { console.log(“init”);

//First, grab the users location if(goodBrowser()) { if(window.sessionStorage.weatherType) loadStyleSheet(window.sessionStorage.weatherType); else getLocation(); }}

4/5

Page 59: Appliness #9 – December 2012

function goodBrowser() { return navigator.geolocation && window.sessionStorage;}view rawgistfile1.jsThis Gist brought to you by GitHub.And then stored the weatherType variable in the user’s session:if(weatherType) { loadStyleSheet(weatherType); //cache in session window.sessionStorage.weatherType = weatherType;}

You can view this version here: http://www.raymondcamden.com/demos/2012/nov/12/index2.html

Page 60: Appliness #9 – December 2012

appliness( DON’T WORRY, BE APPLI

by James Padosley

JS ADOLESCENCESEE SOME OF THE LESSONS JAMES HAS LEARNED ABOUT HOW TO DO (OR NOT TO DO, THAT IS) JAVA-SCRIPT PROGRAMMING OVER THE YEARS.

For me there was a time that can only be described as adolescence in the field of programming and more specifically JavaScript. This period was characterised by a certain laziness and hubris. I thought I was right. I thought others were wrong. I could see no path but the very strict one that I had boxed myself into through a process in which I longed for certainty and the expulsion of realistic doubt.

Today I present a short list of JavaScript practices that once seemed right but I now deem foolish (in most situations):

•Using logical operators as statements

•Always declaring variables at the top of their scope

•Repeatedly used inline object literals

•Complex inline regular expressions

•Using single letter variable names

•Strict equality everywhere

•Assuming truthiness equals presence

•Commenting nothing or commenting every little thing

•Thinking I can write something reliable without unit tests

•Using long names and being overly specific

•Strict coherence to a standard

Page 61: Appliness #9 – December 2012

USING LOGICAL OPERATORS AS STATEMENTS

a() || b.foo.bar(); m && c() ? d() : l || m.foo[bee](3);

There is no real advantage in forgoing convention for the sake of cleverness.

ALWAYS DECLARING VARIABLES AT THE TOP OF THEIR SCOPE

function calculate() { var a, m, t, y, This, is, really, understandable = false; // Actual logic goes here}

Instead I declare a variable where it makes sense. Much of the time this is at the top of the scope, but there are enough exceptions to make me shake my head in dissapproval at the thought of a style guide imposing religious top-of-scope declarations.

REPEATEDLY USED INLINE OBJECT LITERALS

function prepareRequest(mode, updateId, value) { var req = { mode: mode, updateId: updateId, value: value, uid: genUID() }; // etc.}

It’s better for clarity and performance (potentially) to define separate classes for cases where you repeat-edly make object literals of the same structure. For example the above could be refactored into a Re-quest class.

COMPLEX INLINE REGULAR EXPRESSIONS

if (/r[ -~]?(?:m\d+|\d+[0-3]{2,})_m?$/.test(thing)) { // ... wat}

It makes sense to cache these things. Plus naming it means someone might have a chance of understand-ing WTF the code does.

2/4

Page 62: Appliness #9 – December 2012

USING SINGLE LETTER VARIABLE NAMES

They make no sense unless used in the various idiomatic loops.

STRICT EQUALITY EVERYWHERE

if (typeof x === ‘string’ && x === ‘mode:45’) { // ... }

Sometimes it’s overkill. Regular equality can be used in both of the above cases.

ASSUMING TRUTHINESS EQUALS PRESENCE

if (!cachedReturnValues[key]) { cachedReturnValues[key] = value;}

It’s potentially dangerous. E.g., It’s better to use the ‘in’ operator to discover presence, or even ‘hasOwn-Property’.

COMMENTING NOTHING OR COMMENTING EVERY LITTLE THING

// This is a loopfor (var i = 0; i < arr.length; i++) { // This is me adding one to the item in the array at the index // specified by the variable `i` declared slightly above this comment: arr[i] += 1;} // this is the end of the loop

Commenting everything demonstrates either a lacking clarity in your code or a lacking clarity in your mind as to the intention of comments. Commenting nothing shows hubris and laziness.

THINKING I CAN WRITE SOMETHING RELIABLE WITHOUT UNIT TESTS

Unit tests give me the confidence to be sure that my code does what I intend it to do.

3/4

Page 63: Appliness #9 – December 2012

ABOUT THIS ARTICLE

James is a JS Developer with extensive experience in front-end web development. He enjoys challenges, breaking boundaries and doing helpful and inspiring work. He works in London for Lab49 as a UI Devel-oper. He enjoys writing about his latest discoveries, opinions and adventures. Head over to “posts” to see what he’s been distracting himself with lately. http://james.padolsey.com/

@padolsey

ONLINE RESOURCES

James on Githubhttps://github.com/padolsey/

James’s links on Delicioushttp://delicious.com/padolsey

Lab49http://www.lab49.com/

USING LONG NAMES AND BEING OVERLY SPECIFIC

A long name suggests bad API design. Re-think where you’re defining the variable/method. Think of a circumstance in which the variable name could be shorter — a context that makes sense for that variable. Then create that context. You’ll probably end up with a cleaner internal API. E.g.

// Version 1:var responseCache = {};function generateNextIDForANewResponseCacheItem() {...}function deleteResponseCacheItemsThatDoNotEqual(value) {...} // Version 2:function ResponseCache() { this.data = {};}ResponseCache.prototype = { genNextID: function() {...}, remove: function(optionalFnCheck) {...}};

STRICT COHERENCE TO A STANDARD

This never works and never solves what you think it will. It’s better to dynamically sway and constantly re-think your idea of what is right and wrong given each situation as it arises. This is why I try to steer clear of over-zealous coding style dogma, or all dogma for that matter.

Page 64: Appliness #9 – December 2012

PHOTO BY: Elle Osmani

A D D YOSMANITHE MODERN YEOMAN

PHOTOS BY: Elle Osmani

KEVIN LY N C HTHE CREATIVE LEADER

Page 65: Appliness #9 – December 2012

HI KEVIN, THANK YOU SO MUCH FOR YOUR TIME, IT IS A GREAT HONOR TO HAVE YOU FEATURED IN APPLINESS. Thanks for having me! It’s an honor to be featured in Appliness. The team has done a great job with the publication. I am currently CTO at Adobe, and joined through the 2005 acquisi-tion of Macromedia. At Macromedia we really helped imagine and push the boundaries of what the Web can be and developed some really great tools for the early Web. Prior to Macromedia, I was with three startups, two of which went public. One of those startups was Frame Technology, which was also acquired by Adobe. I’ve been making software since I was twelve, and was lucky to find what I loved to do early in life. At Adobe today I’m responsible for shaping our long-term technol-ogy vision and focusing innovation across the company amidst an exciting and transformative time. It’s not only an exciting time for Adobe but for the entire industry.

YOUR CAREER SHOWS A VAST HISTORY OF BLENDING THE CREATIVE WITH THE TECHNICAL. HOW MUCH OF WHAT YOU GET TO DO IS CREATIVE AND HOW MUCH IS TECHNICAL? Great question. To me, creative expression is technical, and at the same time technology opens new doors to creativity. I learned this early on as I worked for a time as a member of the Electronic Vi-sualization Laboratory (http://www.evl.uic.edu) in college. I was an engineer sitting at a workbench right next to artists using the soft-ware we developed. They could literally ask for a feature, we would make it, and they would use it in their electronic art project right then. We would also make up new things, like controlling lasers to appear to draw with persistence of vision, and that would drive a whole new round of creations. It was incredibly intertwined. The most successful creative endeavors in technology have this element of interdependency within the work, and the close connection of the engineers and the artists. The intersection is where the magic happens. Adobe is heavily rooted in this blend of creativity and technology, and is what really keeps me so very engaged here. The challenge is finding the balance that enables us to fuel technology innovation with creative thinking and vice versa. We learn from those in our community who are on the leading edge and then work to main-stream those creative approaches in our software. Finding this bal-ance is the heart of what Adobe is all about.

Page 66: Appliness #9 – December 2012

PHOTO BY: Umesh Nair

VISIONWHAT INSPIRES YOU?

The rate at which technology is accelerating right now, across many industries, is incredibly inspiring. We are in the midst of several groundbreaking technology transformations across mul-tiscreen, cloud computing, and social computing. These trans-formations are moving at an incredibly rapid pace and repre-sent more change than I’ve seen in the industry ever. It’s creating many very exciting opportunities for Adobe and our community. ARE THERE ANY PERSONAL PROJECTS THAT YOU ARE WORKING ON, OR WOULD LIKE TO IF YOU HAD THE TIME?

I’m very passionate about the new projects I’m involved with alongside others at Adobe and take these very personally! We are constantly looking to identify and pursue new research or technology projects—especially in the areas of mobile, touch, cloud, and social computing. However, something I’m particularly excited about right now is the launch of a new site that gives insight into the transformation at Adobe, called Peek (http://peek.adobe.com). Peek is a cel-ebration of the amazing work happening at and around Adobe, and highlights amazing digital content, industry thought leaders, and the artists and creators themselves. New content will be fea-tured every month on Peek as well as blogs and other thoughts from me—check it out! THE WEB HAS BEEN AROUND FOR A WHILE NOW AND HAS UNDERGONE RAPID AND DRASTIC CHANGE SINCE ITS EXIS-TENCE, YET DO YOU THINK WE ARE EXPERIENCING A TIME IN WHICH THERE IS POTENTIAL FOR EXPLOSIVE GROWTH IN THE WEB? Absolutely, the growth continues to be explosive both in the to-

tal number of people connected to the Web, and the technolo-gies and businesses blooming around it. We’ve made amazing progress in building a healthy foundation for the Web and ad-vancing technologies to ensure there is a strong future of con-tent creation and app development online. Adobe is investing in making the Web and HTML5 even more expressive. Particularly right now, we are seeing a revolution online into a really modern (or perhaps post-modern) web platform. We are living in an ecosystem of multiple browsers and vast distribution across operating systems, as well as the cross-over from desktop to mobile devices. There is an explosion in design online—with richer functionality and embracing motion graphics and respon-sive layout in the work. This explosion of growth really requires an entire retooling that is focused on the new reality of web development and design. One in which we’re accounting for multiple screens of different sizes, varying experiences, dynamic content and hardware-accelerated graphics. FOR MANY YEARS, IT FELT LIKE INNOVATION IN WEB STAN-DARDS WAS STAGNANT, BUT IN THE PAST FEW YEARS, IT HAS BEEN INNOVATING AT A FAST AND ACCELERATING PACE. HOW HAS THIS IMPACTED ADOBE? Yes it has been terrific to see innovation come back on in the web both in standards and in the browsers. Having the browsers back on a rapid release cycle has really helped make the standards real and drives of course the practical reality of what people can express on the Web. For Adobe, the tools that we make continue to help people express themselves creatively on the Web—and the more cre-ative experiences that are possible, the more opportunity and need for creative tooling and technologies. The advancement of expression on the Web is a good thing for Adobe and our com-munity. IS ADOBE HELPING TO PUSH WEB STANDARDS TO NEW HEIGHTS?

Yes, absolutely. Adobe is continuing to contribute to the core infrastructure of the web through open source contributions to WebKit, for example, which is used within the Apple Safari browser and Google Chrome. Engineers across Adobe are par-ticipating in working groups and helping the standards develop, and we’re continuing to contribute code to help drive these in browsers. WE SEE PATTERNS OF ADOBE EXPERTISE AND INNOVA-TION IN WEB STANDARDS. WILL WE SEE MORE OF ADOBE BRINGING ITS EXPERTISE TO WEB STANDARDS?

Definitely. We are active contributors to moving the web for-ward, especially in areas where it will enable even greater ex-pressiveness and creativity. The new browser capabilities we’re seeing lead to new experiences and greater expectations for those experiences. Right now for example, we’re working with W3C to add advanced cinematic features to the web through CSS Custom Filters, which now includes support for developer-created custom filters. Our hope is that these will be broadly adopted across browsers, and then supported with Adobe tools like Edge Animate. We’re also focusing on advancing responsive magazine style layouts with CSS Exclusions and CSS Regions,

Page 67: Appliness #9 – December 2012

PHOTO BY: Umesh Nair

and advancing graphical effects through CSS Blending and CSS Compositing tools. In October, we released a new tool called CSS FilterLab, which allows web designers to quickly learn the syntax of the new CSS Filters specification by using the tool’s drag-and-drop interface. The built-in filters are already being supported in Safari 6 and Chrome browsers, which means developers can copy/paste the generated CSS code into their pages today. It’s very exciting for us that CSS FilterLab is open-source and written in web technol-ogies itself—it’s posted on GitHub right now if you’re interested in checking it out. ONLY A FEW YEARS AGO, WEB DESIGNERS ONLY HAD TO WORRY ABOUT FAIRLY LARGE, LANDSCAPE ORIENT-ED SCREENS, BUT NOW, THEY HAVE TO WORRY ABOUT SCREENS OF VARYING ASPECT RATIOS AT WIDTHS OF 320 PIXELS ALL THE WAY UP TO 2880 PIXELS. DO YOU SEE THIS CHALLENGE AS AN OPPORTUNITY FOR ADOBE? Yes this is an exciting opportunity, and one we had anticipated and are taking advantage of. There are also varying resolutions in addition to sizes, particularly with newer HiDPI displays. There is indeed an explosion of target screens now for our cus-tomers - it’s no longer one size fits all - so there is a need for responsive design, which is design that responds to the environ-ment it’s being displayed in. We are working on this across our software and you can see this already appearing in tools such as InDesign, which now supports responsive layout of page designs including the ability to tie together element positioning and in-dicate where items should move or resize. We also support mul-tiple layout design in Dreamweaver for websites, and in our new generation of tools such as Edge Reflow which is built from the ground up with responsive design as its essence. In some ways, a smaller screen enables a necessary degree of simplification that really helps improve the overall design—when real estate is premium, more thinking goes into the UI and over-all experience as you have to make more choices and prioritize the really key items.

“Adobe is heAvily rooted in this blend of creAtivity And technology, And is whAt reAlly keeps me so very engAged here.”

Page 68: Appliness #9 – December 2012

PHOTO BY: Umesh Nair

CLOUDHOW IMPORTANT WAS IT FOR ADOBE TO OFFER HOSTED SERVICES? It’s vital—it is not an overstatement to say Adobe will not survive without reinventing ourselves for the cloud. This is also for touch interfaces. The revolution is afoot and we are changing with it to create the next generation of Adobe. This is actually the fourth reinvention of Adobe since its founding, and we are fortunate our culture embraces change. Software in boxes is a technology phase that is in the process of going away. It’s already increasingly odd to go to a physical store and buy a box of software. This is much like how other digital media has transitioned from the physical world to the virtual. Embracing this change is just one part of our move to the cloud. We are working on two major cloud efforts, across our creative business and digital marketing business. We’ve been focusing on transitioning our creative business to Creative Cloud, and we’ve seen huge success already—much more than originally anticipated. We have more than 1 million Creative Cloud customers, a third of which are paying—this is incredible movement in just the short time since Creative Cloud has been available. For marketing we are introducing Marketing Cloud, which en-ables people to get insight on the effectiveness of their creative, the relationship to their business, and take action to optimize it. We are also now working to connect these two clouds for our customers to enable even better collaboration across creative and marketing teams. There is no other company making a con-nection like this today and it will be a great competitive advan-tage for our customers.

WHAT ROLE DOES CREATIVE CLOUD PLAY IN ADOBE’S FU-TURE AND SUSTAINABLE SUCCESS? Creative Cloud is playing a central role in the future of Adobe. It is a reimagining of how we build and deliver our creative soft-ware, and is expanding to include a wide variety of hosted ser-vices in addition to the classic creative tooling that is familiar to everyone. It also will become a place to be, not just a place to get and use tools, as we establish in Creative Cloud the founda-tion for the creative community around the world to connect and be inspired by one another. The benefits of cloud computing also greatly come into play in Creative Cloud, such as online services for file sharing, collabora-tion, publishing, automatic feature updates, greater enterprise control, and a more attractive pricing model for customers. Creative Cloud is enabling our teams to deliver new capabili-ties much faster than we could with the major release model of shrink-wrapped software. Moving to a membership model is also enabling access to a number of new customers, and building a more predictable recurring revenue business for Adobe. We are already seeing great success with the adoption of Creative Cloud. The fact that we were not only able to embrace such a dramatic change in an approximate $3 billion business—but that we are already seeing strong adoption—is a good indicator of our success with Creative Cloud. We are embracing the new world.

Page 69: Appliness #9 – December 2012

PHOTO BY: Umesh Nair

NEXT WHAT ARE YOUR HOPES FOR 2013?

2013 will be a big year for Adobe, and one in which we’ll see at a much larger scale the success of our business transformation. Strategically, I’m continuing to look at technology trends across multiscreen (including touch and mobile), cloud, and social com-puting and working with our teams to take advantage of these more fully. We’ll be connecting Creative Cloud and Marketing Cloud to support collaboration across teams, which will be very exciting to deliver. Within Creative Cloud, we’ll also build further on our services—possibly even looking at new ways in which we could stream our creative applications, for example, through Creative Cloud. And in addition to creative services for professionals, you’ll be seeing more new software and cloud services from Adobe to enable everyday creativity for everyone. Finally, research and engineering teams at Adobe are continuing to work on some really breakout work for both creativity and in working with big data in marketing. I’m looking forward to un-veiling some of the things that we have in the works when the time is right—I think everyone will be pleasantly surprised.

“the tools thAt we mAke continue to help people express themselves creAtively on the web.”

Page 70: Appliness #9 – December 2012

appliness( DON’T WORRY, BE APPLI

by Brett van Zuiden

DESIGNING JAVASCRIPT APISWE AT FILEPICKER.IO SPEND A LOT OF TIME THINKING ABOUT APIS. WITH THE RELEASE OF OUR VER-SION 1.0 JAVASCRIPT API, WE THOUGHT ABOUT BEST PRACTICES FOR JAVASCRIPT API DESIGN, AND WANTED TO SHARE THEM SO THAT WHEN WE USE YOUR API, IT’LL BE JUST AS AWESOME AS WHEN YOU USE OURS. CLICK HERE TO SEE THE ORIGINAL BLOG POST.

RULE 0: NEVER MAKE BREAKING CHANGES TO YOUR API. UNLESS YOU MUST.

An API is a contract between you and the developers who use your product. Don’t violate it. Unless it’s a terrible contract and you would both be better off moving to a better place.

The developers building on your API have invested time and energy into learning how to use your prod-uct and integrating it into theirs.

However as your knowledge about how people are using your product and API grows, the original API will become stale and a refresh will be in order. Wait until the cruft is unbearable, then in one giant leap move as far forward and future-proof as you can. Do it all at once in one clean break. If you can, provide a shim that maps the old API calls to the new one, so that someone can include the new API and a shim and not break any of their old calls.

Over the course of our early customer development during YC, the product and feature set was chang-ing so fast it essentially meant we just piled more and more on to the API. It worked, but in dealing with our API, there were all sorts of inconsistencies, rough edges, almost-theres, gotchas, etc. So we made the tough call of redesigning our API from the ground up as a V1, and our developers seem pleased with the result.

Page 71: Appliness #9 – December 2012

RULE 1: PROVIDE WOOD AND NAILS, AND A COMPLETE HOUSE FOR YOUR API

Provide high-level functionality that completes a whole workflow in one line of code, and also raw primi-tives that allow a developer to build up entirely custom functionality. Things in the middle are just frus-trating and confusing.

If someone comes to you asking for help building a house, there are two useful things you can do for them: give them a house, or give them the tools, instruction, and raw materials they need to build it themselves. If you give them three pieces of wood nailed together, it’s just frustrating: they’ll either find ways to rip it apart into the pieces they need, or they’ll have to wedge it into their application in an awkward way.

In the case of our API, we used to provide getFile, which would pick a file from Facebook, Google Drive, etc., optionally perform some conversions, and then store the result for you. Because of all the different things it did, configuring it was a mess. The developer had no way of getting progress, using individual components without the rest. Now, we have, amongst others, filepicker.pick, filepicker.store, and filepick-er.convert, primitives that you can interweave and cascade as you see fit. We also have the HTML widgets which do the most common case in one line of code, perfect for people who just want basic uploading.

RULE 2: HAVE NOUNS, VERBS, AND A COMPLETE BIPARTITE GRAPH

Spec out what objects you pass around and what operations you can perform. You know you found a good candidate for a complete API when you can perform every action on every object.

It helps to think of your API in terms of nouns and verbs which developers can use to form sentences. Draw a grid, with the models/nouns/objects on the one axis and the verbs/actions on the other. Fill in a square if you can perform the given action on the given object. Any blank square will require a special warning in the documentation that explains why you can’t perform the action you wanted. It will require the developer to go back to their API docs every time he wants to do this one action you don’t allow, and will result in support tickets. If you can fill in every square, consider that a complete “block”, a good candidate for an API design.

In our case, our v0 would sometimes return urls, other time JSON blobs, certain ones could be cascaded into other actions but other ones couldn’t. In the new version, everything turns into an FPFile (a JSON for-mat we use as our standard), which can then be used directly in filepicker.store, filepicker.read, filepicker.write, filepicker.convert, and filepicker.export.

RULE 3: WHEN DEALING WITH APIS FAIL FAST, OR BETTER, NOT AT ALL

When dealing with APIs programming errors should throw exceptions immediately. User errors or unex-pected situations should pass back errors in a consistent fashion. Be willing to do extra work in the library to follow the principle of least surprise. Your API will thank you. Come up with a consistent way of treat-ing errors, but here’s a scheme that we found particularly nice for javascript:

Developers should never have to use a try-catch. Exceptions are thrown in situations where the developer made an error (or you made the error of not documenting well enough) and should be alerted as soon as possible.

When unexpected things happen or the user does things that are “error-like” (closing the dialog without choosing something, uploading content that can’t be read, etc.), pass back a consistent error type in a consistent way. For us, we have an onError(FPError){} callback on each function. By default the error con-tains a lookup code, but we also have a filepicker-debug.js library that will automatically inject helpful er-

2/3

Page 72: Appliness #9 – December 2012

ABOUT THIS ARTICLE

Brett van Zuiden is CEO and Founder of Filepicker.io, a product for developers that helps their web and mo-bile applications better work with user content, pro-viding an SDK that performs accelerated uploading, image conversion, and integration with cloud sources like Facebook Photos, Dropbox, and Google Drive. https://www.filepicker.io/

@FilePicker

ONLINE RESOURCES

JavaScript API on Filepicker.iohttps://github.com/padolsey/

Demos on Filepicker.iohttps://www.filepicker.io/demos/

Docs on Filrepicker.iohttps://developers.filepicker.io/docs/

ror messages into the FPError.toString() method. This way we keep our library lightweight for production while still helping developers in development mode.

When interfacing with the API, see if there are things that your library can do which may take a little bit of extra work on your code, but will catch common mistakes. For instance, if you want to limit the user to only selecting images, you can set {mimetype: “image/*”}, or {mimetypes: “image/*”}, or {mimetypes: [“image/*”]}. The filepicker.read() call accepts FPFiles, URLs, DOM File objects, and DOM input types. If you try to read a file in IE8, rather than fail, the library will jump through hoops to perform the action (see post), but to you the developer, it’s magic - things just work so you don’t have to futz with exceptions and error cases.

RULE 4: IF THE API IS HARD TO USE, IT’S NOT GOOD ENOUGH

Use your API as you’re building it. Try writing to the API before you even build it, and get some of your lead customers/friends to do the same.

The first thing we did in specifying the API was convert all our demos to the “new” design. If something felt awkward, we redesigned it. The API required too much boilerplate to do simple things, we simplified it. We ran through the same exercise with our customers, writing up a quick guide and having them look at migrating their implementation. It was only after we loved using our API internally and our customers loved it that we built it. This was now fun, because once we had played with what the V1 of our API would be like, we couldn’t wait to see it go live. If you want to try it out yourself, check out our documentation page, now with run-able, editable API code samples: https://developers.filepicker.io/docs/web/

In summary:

Never make breaking changes to your API. Unless you must.

•Provide high-level functionality in one line of code, and also the raw primitives.

•Have nouns, verbs, and a complete bipartite graph.

•User errors with your API or unexpected situations should pass back errors in a consistent fashion.

•If your API is hard to use, it’s not good enough (meaning you have to use it first)

Try out the newest version of our javascript API.

If you’re interested in API design, there’s a burgeoning field of “Developer Experience” that might inter-est you.

•John Resig on javascript API design (some is a bit outdated, but good principles): http://www.youtube.com/watch?v=0LKDImgRfrg

•Pamela Fox on API design at Google, etc. http://vimeo.com/27216846

•General information on “developer experience” for APIs: http://developerexperience.org/

Page 73: Appliness #9 – December 2012

appliness( DON’T WORRY, BE APPLI

by CJ Gammon

FUN WITH BUILT-IN CSS FILTERSMAKE SURE YOU HAVE INSTALLED IOS6 ON YOUR IOS DEVICE AND ENJOY THE NEW CSS FILTERS.

CSS FILTERS ON IOS6

With all the buzz around CSS Custom Filters, you’re hopefully aware of all the cool effects you can play around with in Chrome Ca-nary using our CSS FilterLab. While we have to wait for CSS Custom Filters to hit main-stream browsers, you can use CSS Filter Lab to play with built-in CSS filters already avail-able in most WebKit browsers today, includ-ing Chrome, Safari, and even Mobile Safari on iOS6.

These come to us from the world of SVG, where built-in filter shortcuts could be ap-plied to SVG elements, but we will focus on the CSS specification here. Built-in filters are easy to use by simply applying the filter prop-erty and using a filter func-

tion, which accepts a value as a parameter.

This is very similar to how CSS Transforms work. You can even apply mul-tiple filters in the same filter property, the same way you can apply multiple transforms. In these examples, I will be using the un-prefixed filter prop-erty, but current release versions of Chrome and Safari use the -webkit- experimental prefix.

Page 74: Appliness #9 – December 2012

PHOTO FILTER DEMO

It is possible to combine these filter functions in interesting ways to simulate complex photo filter effects. You can extend the visuals even further by layering the same element at varying opacity with different fil-ters applied. We used a combination of filter functions to create a Photo Filter demo that we showcased at The Create The Web event in SF. This demo is now available on GitHub.

Here is what we used to create an Old-Style photo effect:

filter: sepia(0.8) saturate(3) brightness(0.25) contrast(2);

You can use many other built-in filter effects in tandem. The available built-in filters are:

– grayscale – sepia – saturate – brightness – contrast – opacity – invert – hue-rotate – blur – drop-shadow

Take a look at our code to find many ways these functions can be used to create complex photo filters. You can also read more about the built-in filters and their values in the specification.

As built-in CSS Filters are already available in Chrome, Safari, & Mobile Safari on iOS, you can start play-ing with them today and see how they can be used to enhance your web application. The CSS FilterLab is a great resource to play with filters and instantly see the results. Now let’s try a live demo on your device:

>

2/3

Page 75: Appliness #9 – December 2012

THE LIVE DEMO

Make sure you are using iOS 6 and play with this live sample:

Filters:

B&W-webkit-filter: grayscale(1);

Sepia-webkit-filter: sepia(1);

Saturate-webkit-filter: sepia(0.2) saturate(3) contrast(1.2);

Old Style-webkit-filter: sepia(0.8) saturate(3) brightness(0.25) contrast(2);

Vincent-webkit-filter: hue-rotate(40deg) contrast(3);

Arno-webkit-filter: hue-rotate(200deg) contrast(1.2) saturate(2);

Ethan-webkit-filter: hue-rotate(260deg) contrast(1.2);

Soft Blur-webkit-filter: blur(10px) grayscale(0.8);

Page 76: Appliness #9 – December 2012

appliness( DON’T WORRY, BE APPLI

by Antanas Marcelionis

GETTING STARTED WITH JAVASCRIPT MAPSCHECK OUT THESE COOL TOOLS FOR CREATING INTERACTIVE MAPS USING SVG TO RENDER MAPS.

INTRODUCTION TO JAVASCRIPT MAPS

JavaScript amMap is a piece of software for creating interactive maps for your web sites and applications. It’s quite different from mapping products like Google Maps, and so is its purpose. We do not provide deep-level maps like Google Maps does. We offer world map, continents map and a lot of country maps with district borders. We do not offer city maps or satellite images, our maps consist of pure country/dis-trict areas. Here are some examples of our mapping tool in use:

•United States Heat Map

•Interactive Flight Route Map

•Drill-down map

•Grouped countries map

•World capitals map

•Zooming to countries map

Our tool uses SVG to render maps. We do not offer VML which would be needed to support Internet Ex-plorer browses version 8 and older. VML is simply too slow to handle this amount of vector data. Sorry legacy browser lovers ;)

Page 77: Appliness #9 – December 2012

CREATING YOUR FIRST MAP

Download amMap package, unzip it to some folder and copy “ammap” folder to your working directory. Now open your HTML file (I will assume that it is in the same level where you copied ammap folder). First, you should include ammap.js into header of your HTML:

<script src=”ammap/ammap.js” type=”text/javascript”></script>

In case you are using our amcharts js file in the same page, you can insert ammap_amcharts_extension.js instead of ammap.js – this will save you ~50 kilobytes. Remember, you have to insert ammap_amcharts_extension.js after amcharts.js (or amstock.js) file!

Next, you have to insert map file too. Actually there are two ways of using maps – you can load SVG files at runtime or insert maps as .js files. We recommend inserting maps as .js files as it is much more reliable - some servers do not like SVG format. Also you will not be able to test maps without web server if you load them as SVG.

To insert map file as .js file simply add this line to your HTML (after the line where you inserted ammap.js file!):

<script src=”ammap/maps/js/world_low.js” type=”text/javascript”></script>

You can use any other map – just go to the ammap/maps/js folder and check the available maps (we are adding new maps constantly).

Side note: we include two versions of each map – high detail and low detail. Normally you should always use maps with “_low” suffix as they are faster and less resource-intensive. If your particular purpose calls for for greater detail and you’re willing to potentially sacrifice some performance for it, go with the “_high” version.

In case you wish to load maps as SVG files – read on, we’ll cover this a bit later.

Next, you should create a div which will hold your map. Add this to your HTML body:

<div id=”mapdiv” style=”width: 600px; height: 400px;”></div>

Now we’ll do some JavaScripting. Below is a script with comments which should produce a simple World map:

// add all your code to this method, as this will ensure that page is loaded AmCharts.ready(function() { // create AmMap object var map = new AmCharts.AmMap(); // set path to images map.pathToImages = “ammap/images/”; /* create data provider object mapVar tells the map name of the variable of the map data. You have to view source of the map file you included in order to find the name of the variable - it’s the very first line after commented lines. getAreasFromMap indicates that amMap should read all the areas available in the map data and treat them as they are included in your data provider. in case you don’t set it to true, all the areas except listed in dataprovider will be treated as unlisted. */ 2/8

Page 78: Appliness #9 – December 2012

var dataProvider = { mapVar: AmCharts.maps.worldLow, getAreasFromMap:true }; // pass data provider to the map object map.dataProvider = dataProvider; /* create areas settings * autoZoom set to true means that the map will zoom-in when clicked on the area * selectedColor indicates color of the clicked area. */ map.areasSettings = { autoZoom: true, selectedColor: “#CC0000” }; // let’s say we want a small map to be displayed, so let’s create it map.smallMap = new AmCharts.SmallMap(); // write the map to container div map.write(“mapdiv”); });

Now, if you open your HTML file in a browser, you should see this:

Try to click on any country – the map will zoom-in on it. You can also drag, pan the map or click on a small map to move the big one to the desired position. In case you don’t see the map, check error console – most likely it will show some errors. It’s a first to-do if something is not working. 3/

8

Page 79: Appliness #9 – December 2012

LOADING SVG MAPS

In case you wish to load SVG maps instead of including them as .js file, all you need to do is to change mapVar of your data provider to mapURL and specify path to the SVG map, for example:

mapURL: “ammap/maps/svg/world_low.svg”,

However, as we mentioned, it’s not as reliable as including maps as .js files.

MANIPULATING AREAS (COUNTRIES)

Let’s say we want to change color of some of the countries. This should be done by adding these coun-tries to data provider and specifying color of your choice. Map data provider is an instance of MapData object, check our docs to find more of what it is capable of.

Each country/area has an id. For world map we use ISO country codes like US, UK, DE for id’s. For coun-tries administrative areas we use id’s like AU_WA where AU is ISO code of the country (Australia in this case) and WA is id of the administrative area. All the available areas are listed in each map’s .js and .svg files, in JavaScript array which you can copy/paste directly to data provider. I left only some of the coun-tries, as I don’t need them all:

var dataProvider = { mapVar: AmCharts.maps.worldLow, areas:[{id:”AU”},{id:”US”},{id:”FR”}] };

Note, I deleted getAreasFromMap:true from data provider, as now I want all the areas except those three to be inactive. The result is this:

4/8

Page 80: Appliness #9 – December 2012

All the areas except listed are now grey. This color is set via AreasSettings unlistedAreasColor property. You can also control opacity, outline color and opacity of unlisted areas.

The three areas we included are colored with color set via color property of AreasSettings. Check all the available properties to get impression of what else you can change. As you have correctly guessed, the settings you set for AreasSettings are applied for all listed areas, but only if you don’t set some property of the area explicitly.

Each country/area object listed in your data provider is an instance of MapArea. Check docs to see list of available properties. Let’s say we want each of the three countries to be filled with a different color. The property responsible for this is “color” (surprise!). So we modify data provider by adding color with some HEX color code to each country:

var dataProvider = { mapVar: AmCharts.maps.worldLow, areas:[{id:”AU”, color:”#CC0000”},{id:”US”, color:”#00CC00”},{id:”FR”, color:”#0000CC”}] };

And the result is now:

You can modify color, opacity, title (titles are hardcoded in a map, but you can simply change them using “title” property), add description which will popup if user clicks on a country and do a lot more.

ADDING AN IMAGE TO A MAP

Let’s say I want to add some icon on the map in the place where New York City is. This will also be done via data provider, images property. Images are instances of MapImage object. Images can be placed in two ways – by setting it’s position using left/top/right/bottom properties or by setting latitude and lon-gitude. If you set latitude and longitude, the image will be bound to the map position – it will move to- 5/

8

Page 81: Appliness #9 – December 2012

gether with it. Otherwise the image will stay in the same place. As I want to mark New York City, I need to set latitude and longitude. So I went to Wikipedia and found that latitude is 40.3951 and longitude is -73.5619.

MapImage has “type” property which can be set to one of the three values: circle, rectangle and bubble. I choose “bubble” this time and set its color to velvet:

var dataProvider = { mapVar: AmCharts.maps.worldLow, images:[{latitude:40.3951, longitude:-73.5619, type:”circle”, color:”#6c00ff”}] };

Note, I deleted areas so that they wouldn’t steal your attention. And here is the result:

As you can see, there is a red circle in the place where New York City is! Most of the maps we provide are calibrated, so real world latitudes and longitudes can be used. Only some of the maps for some techni-cal reasons can not be calibrated (for example map of US where Alaska an Hawaii are shifted so that they would be close to mainland).

You can still find longitudes/latitudes (and also a lot more information required to build maps) both for calibrated and non-calibrated maps using developer mode. Check developerMode.html example in sam-ples folder to see it in action.

Now I want to change the red circle to some more interesting picture. You can load gif, png, jpg or svg files by setting imageURL for your image with path to the image. However loaded images have limita-tions – you can not change colors, set outline and some more. The recommended way of adding single-color images to the map would be creating variable of SVG path and setting it via svgPath property of MapImage. I recommend visiting Raphael’s icons set page to get SVG paths for a lot of nice icons. Simply choose the icon you like and copy the path. Then you can create variable (so you could use it more than once) and set this variable as svgPath of your image:

6/8

Page 82: Appliness #9 – December 2012

var icon= “M21.25,8.375V28h6.5V8.375H21.25zM12.25,28h6.5V4.125h-6.5V28zM3.25,28h6.5V12.625h-6.5V28z”; var dataProvider = { mapVar: AmCharts.maps.worldLow, images:[{latitude:40.3951, longitude:-73.5619, svgPath:icon, color:”#CC0000”, scale:0.5, label:”New York”, labelShiftY:2}] };

Note, I deleted type (we don’t need it anymore) and set scale to 0.5 so that the icon wouldn’t be too big, I also added “label” property with value “New York” and adjusted label’s vertical position by 2 pixels so that it would fit better. And the result (after I manually zoomed in) is:

ADDING SOME INTERACTIVITY

Now I want to make the New York icon clickable and I want the map to zoom-in and display some more information when user clicks on it. MapImage has all the properties you need to do that: value set as de-scription will be displayed in a popup window, zoomLevel will tell how much do you want to zoom-in:

var icon= “M21.25,8.375V28h6.5V8.375H21.25zM12.25,28h6.5V4.125h-6.5V28zM3.25,28h6.5V12.625h-6.5V28z”; var dataProvider = { mapVar: AmCharts.maps.worldLow, images:[{latitude:40.3951, longitude:-73.5619, svgPath:icon, color:”#CC0000”, scale:0.5, label:”New York”, labelShiftY:2, zoomLevel:5, title:”New York”, description:”New York is the most populous city in the United States and the center of the New York Metropolitan Area, one of the most populous metropolitan areas in the world.”}] }; 7/

8

Page 83: Appliness #9 – December 2012

ABOUT THIS ARTICLE

Antanas Marcelionis failed as a blogger and has decided he likes coding more. His company, amCharts, based in Vilnius, Lithuania had its be-ginnings in 2004 when Antanas created the first version of amMap. In 2006, Antanas left his job as a manager at a web development company & the rest is history.http://www.amcharts.com/ @marcelionis

ONLINE RESOURCES

amCharts official websitehttp://www.amcharts.com/

amCharts bloghttp://blog.amcharts.com/

SVG official websitehttp://www.w3.org/Graphics/SVG/

Now, after you click on “New York” icon, the map will zoom in and display description:

That’s it for this tutorial. You can do a lot more – drill-down maps, heat maps. Not only you can display images but also draw lines on top of the map. You can use amMap together with amCharts and create stunning data visualizations. Good luck!

Page 84: Appliness #9 – December 2012

appliness( DON’T WORRY, BE APPLI

by David Deraedt

BUILDING YOUR FIRST BRACKETS EXTENSIONBRACKETS IS AN OPEN SOURCE CODE EDITOR FOR THE WEB, WRITTEN IN JAVASCRIPT, HTML AND CSS. DAVID EXPLAINS IN THIS ARTICLE HOW TO WRITE CUSTOM EXTENSIONS FOR THIS IDE USING WEB STAN-DARDS.

BRACKETS, THE OPEN SOURCE IDE FOR THE WEB

Brackets, the new open source code editor for the web, takes extensibility very seriously. In fact, some of its core features are implemented as extensions, such as Quick Open, Quick Edit, and HTML Code Hint-ing.

Brackets has a highly modular architecture that enforces separation of concerns by keeping the Brackets main code as focused as possible, while it is still deeply customizable—an absolute requirement to fit modern web developers’ needs.

You may notice, however, that while Brackets comes with some default extensions, out-of-box it still might seem a bit limited. For that reason, the first thing new users can do is to install extra extensions, as described in my blog post: Brackets/Edge Code extensions you should install right now. By doing so, you will have access to extensions, such as string manipulation or code snippets.

That said, as a user, you’ll probably quickly find yourself thinking “if only Brackets could X... how hard can it be?” Well, since Brackets is built using web standards, as described in the article, Brackets: The Open Source Code

Page 85: Appliness #9 – December 2012

Editor for the Web, by Adam Lehman, customizing it by yourself is far easier than you might imagine. It’s also a very rewarding experience—one you can quickly get hooked on.

In this article, we’ll take a look at how Brackets extensions work, how you can build one using a template or starting from scratch, and how to best set up your development environment.

Note: While Edge Code is a Brackets distribution that you can use to potentially build extensions too, it does not come with a Debug menu, making it less convenient than Brackets for the job of writing exten-sions. You can, however, use any extension you create with Brackets within Edge Code. This article was written using Brackets Sprint 16..

EXTENSIONS LOCATION

Technically speaking, an extension is nothing more than a folder containing a JavaScript file named main.js, which is executed by Brackets at startup.

When it finished loading and executing the rest of its code, the application will look for those extensions in the following folders:

- The default extensions folder (src/extensions/default). This folder contains default extensions that the Brackets team has chosen. Users should not put anything in this folder.

- The user extensions folder (/Users/<user>/Library/Application Support/Brackets/extensions/user on OSX or C:\Users\<user>\AppData\Roaming\Brackets\extensions\user on Windows 7). Brack-ets users put downloaded third-party extensions from Github within this folder. For convenience, Brackets automatically opens this folder when you select Help > Show Extensions Folder.

- The extension development folder (src/extensions/dev). As an extension developer, you place your own extensions within this folder. This is a more convenient place for them than the user ex-tension folder, which ties into the user system.

Note that Brackets provides a place for disabled extensions, at src/extensions/disabled, which makes it easy to temporarily disable extensions without having to delete them altogether.

2/8

Page 86: Appliness #9 – December 2012

SETTING UP BRACKETS FOR DEVELOPMENT

To debug an extension within Brackets, use the following steps.

1. Within Brackets, select Debug > Show Developer Tools to open the Chrome developer tools. Note that, in the current version (sprint 16), Brackets opens the Chrome developer tools in a Chrome browser window (or opens Chrome if it was closed). On Macintosh, if you use Spaces, ensure that you have a Chrome window open alongside Brackets.

2. I strongly recommend that you disable the cache in the developer tools tab opened from Brackets, otherwise you won’t be able to test your changes, even after reloading the application. You can do that from the developer tools option panel.

3. You’ll quickly realize, however, that writing code and testing the result within the same editor window is just not the way to go. This is exactly why it is preferable that you open a New Brackets Window under the Debug menu, but selecting Debug > New Brackets Window (Figure 4).

I also strongly recommend testing from this second window. To do so correctly, you must set up the de-veloper tools from this window, as explained in step 1. My typical setup looks like the following:

Page 87: Appliness #9 – December 2012

:

WORKING FROM A BRACKETS REPOSITORY CLONE

Another good practice is to develop your code from a separate copy of the Brackets source. The advan-tage is that you can work with the latest version of the application code, ensuring your extension is up-to-date. You also avoid having to edit the original application source, which could have some undesirable effects. A simple way to work from a Brackets repository clone would be to just fork or clone the Brackets repository from GitHub as described in the following steps.

1. Go to the Brackets repository from GitHub.

2. If you have the GitHub client for Mac or GitHub client for Windows, simply click the “Clone in Mac” or “Clone in Windows” button (depending on your platform) from this repo homepage, and choose and a local destination on your disk.

3. Specify that Brackets should run this code instead of the default application contents by pressing shift while you launch the app.

To better understand what I mean by this, it is important to understand that the Brackets application is actually made up of two parts:

- On the one hand, you have the Brackets shell built with the Chromium Embedded Framework, which executes local web content within a native desktop application shell.

Page 88: Appliness #9 – December 2012

- On the other hand, you have local web content such as HTML, CSS, and JavaScript files, which are the Brackets editor source code.

By default, the Brackets shell executes the web files stored within the application content folder, which was created when the application was installed. It is not recommended that you edit code directly from this folder, however. As a result, the native application has the capacity of running from within a different source folder by pressing and holding the Shift key while launching the app. Alternatively, you can use the setup_for_hacking script included under the tools folder of the application source code. You can get this script in from the article, How to Hack on Brackets, on GitHub.

USING AN EXTENSION TEMPLATE

While you can of course write an extension from scratch, it’s preferable to start with a template. Several options are available for you to choose.

A typical way to begin with extension development is to copy and paste an existing extension relatively close to what you want to achieve. This is a valid way to get started, but keep in mind that not all exten-sions are up to date, and that not all necessarily showcase the latest best practices. Also, some exten-sions can be really hard to read, especially if you’re new to extension development.

Alternatively, you can use the Brackets Extension Toolkit, which provides you with a dedicated template, which you can just drag and drop to the src/extensions/dev folder. The toolkit also comes with heavily commented code to guide you through your first development experience of extensions, and the toolkit also provides related helper tools.

Whatever option you choose, once you’re relatively comfortable, I recommend storing your own custom template in the src/extensions/disabled folder to access it quickly later. Simply copy it to the user exten-sions folder.

INTRODUCTION TO THE BRACKETS EXTENSION API

If you look at an existing extension for the first time, chances are that you’ll feel a bit lost. Brackets ex-tensions are JavaScript modules as specified by RequireJS’ Simplified CommonJS Wrapper. Understand-ing JavaScript modules is outside the scope of this tutorial, however, for more information, see Modern Modular JavaScript Design Patterns, by Addy Osmani. For demonstration purposes, let’s assume that in its simplest form, an extension would look like the following:

define(function (require, exports, module) { ‘use strict’; // Extension code goes here console.log(“Extension initialized”);});

All the code within the body of the anonymous function inside the define call executes at application startup.

Of course, most of the time, what you want to build is an extension that makes it possible to execute some code when another part of the application invokes the extension. For example, when a user selects a menu item, this causes your application to execute an action.

Page 89: Appliness #9 – December 2012

You can code this kind of mechanism through commands. You register a command ID with a function so that when the app invokes the ID, a function executes. This is the job of the CommandManager. As with pretty much everything in Brackets, the CommandManager itself is a module. To access other modules from an extension, simply call the dedicated brackets.getModule() method, passing to the method the path to the module relative to the src folder. Notice how the code below does not specify the JS file extension.

var CommandManager = brackets.getModule(“command/CommandManager”);

To specify to the CommandManager which function to execute, and when, specify the register(name, command_id, function) method. The parameters within this method are as follows:

The name parameter is a readable user-friendly name, which is also used as a menu label in the user in-terface.

The command_id parameter is a string to uniquely identify this command. Format it as follows: [author].[my_extension].[menu_name].[my_command_name].

The last parameter, function, is the function the method calls when a user selects a menu item in the UI. When a user selects a menu item in the UI, the app automatically calls execute(command_id) method with the corresponding ID, as shown in the following code example.

var COMMAND_ID = “dderaedt.tutorialExt.logHelloWorld.logHelloWorld”;var COMMAND_NAME = “Log Hello World”;

function sayHello() { console.log(“Hello World”);}

CommandManager.register(COMMAND_NAME, COMMAND_ID, sayHello);

At this stage, the extension is functional but will never be called since something must invoke the com-mand ID. To do so, we add a menu item through the Menus module to invoke the corresponding com-mand ID, resulting in the execution of the function. To do so, we’ll first access the Menus module, as fol-lows:

var Menus = brackets.getModule(“command/Menus”);

Then, we’ll get a handle to the menu we want to add our item to (the File menu, in this example).

var fileMenu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU);

Finally, we simply add an item corresponding to the command that we wish to trigger, as follows:

fileMenu.addMenuItem(COMMAND_ID);

The resulting code for this Hello World extension is as follows:

define(function (require, exports, module) { ‘use strict’;

var CommandManager = brackets.getModule(“command/CommandManager”); var Menus = brackets.getModule(“command/Menus”);

var COMMAND_ID = “dderaedt.tutorialExt.LogHelloWorld”;

Page 90: Appliness #9 – December 2012

var COMMAND_NAME = “Log Hello World”;

function sayHello() { console.log(“Hello World”); }

CommandManager.register(COMMAND_NAME, COMMAND_ID, sayHello);

var fileMenu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU); fileMenu.addMenuItem(COMMAND_ID);});

EDITING THE CURRENT DOCUMENT

Now, to do something slightly more useful, let’s pretend we want our extension to generate some code inside the current document.

In Brackets, files opened in the tool are represented as instances of the Document class. To get a refer-ence to the current document (in other words, the file the user currently has open and editing), we need to use the DocumentManager module. First, we must get a reference to this module, which is inside the document folder.

var DocumentManager = brackets.getModule(“document/DocumentManager”);

Now, starting from the code in the previous section, rename the sayHello() function to addSomeText().

The first thing we’ll need to do inside this function is get a reference to the current document.

var currentDoc = DocumentManager.getCurrentDocument();

Now you can use the Document API, which can help you work with the text content. Here are some of the available methods:

- getText() returns the whole text content

- setText() set the whole text content

- getRange(start, end) returns part of the text content

- replaceRange(text, start, end) replaces text in a given position

Note that the position in the text (such as the start and end parameters above) are expressed through a position object, which contains two properties: line, the line number, and ch (the character number).

In the following scenario, pretend that we want to generate a one-line comment at the location of the current cursor position. Since the Editor object manages code editing, you must get access to the current editor instance as returned by the EditorManager.getCurrentFullEditor() method. So after you make sure to import the corresponding module, as follows:

var EditorManager = brackets.getModule(“editor/EditorManager”);

Page 91: Appliness #9 – December 2012

You can access the editor for the current document, as follows:

var editor = EditorManager.getCurrentFullEditor();

Finally, you can then use the editor to do all sorts of operations related to text selection, such as:

- getSelectedText()

- setSelection(start, end)

- selectWordAt(position)

- getCursorPos()

Now that you have access to all you need, you can rewrite the addSomeText() function, as follows:

function addSomeText() { var currentDoc = DocumentManager.getCurrentDocument(); var editor = EditorManager.getCurrentFullEditor(); var pos = editor.getCursorPos();

currentDoc.replaceRange(“//Black magic. Do not modify EVER”, pos);}

WHERE TO GO FROM HERE

Of course, such simple examples will only get you so far. You’ll quickly need to learn more about the APIs exposed by other modules. The following are some useful resources to learn more about it:

Brackets’ source code itself is, of course, the ultimate and only 100% reliable source of information. If you installed the Brackets extension toolkit, simply select Help > Open Brackets src. Start by taking a look at Document, Editor, EditorManager, FileUtils and of course all the default extensions.

The Brackets wiki is full of useful information. In particular, the How to write extensions page covers the basics you should know about. The Brackets extension toolkit includes a shortcut to this wiki under the Help menu.

If you intend to make an extension that edits the code for the current document, it’s a good idea to get familiar with CodeMirror, the project responsible for the underlying code editing logic.

To understand how Brackets works at a higher level, learn more about the Brackets general architec-ture in the article, An overview of Brackets code architecture.

Finally, if you plan to include some UI in your extension, be sure to check the Extension UI Guidelines draft on the Brackets wiki.

Page 92: Appliness #9 – December 2012

appliness( DON’T WORRY, BE APPLI

by Louis Lazaris

CLEARING FLOATS: WHY IS IT NECESSARY EVEN IN “MODERN” BROWSERS?READ HOW TO GET YOUR PHONEGAP APPLICATION APPROVED BY APPLE.

The other day, someone asked me the following question:

“If I understand it right clear float is automatic in most modern browsers right?”

If you’re new to CSS, then it would seem that the answer to this question should be “yes, of course — modern browsers don’t have these types of bugs!” But the necessity to clear floats is not a browser bug; it’s actually, well, more of a CSS feature. And it’s still needed in so-called “modern” browsers (assuming you’re using floats for layout).

This doesn’t mean, though, that clearing floats will always be necessary. The eventual goal of CSS layouts is to never need to use floats for layout. Instead, we want to be able to use a better method.

But clearing floats are a fact of developer lives today, and so I thought I’d explain why clearing them is still necessary, even in “modern” browsers.

WHAT DOES A FLOAT DO?

Here is, in part, how the W3C spec explains what floats do:

“Content flows down the right side of a left-floated box and down the left side of a right-floated box … Since a float is not in the flow, non-positioned block boxes cre-

ated before and after the float box flow vertically as if the float didn’t exist.”

Page 93: Appliness #9 – December 2012

You can see this behaviour demonstrated in the JS Bin below:

Or, visit the live sample on the web: http://jsbin.com/azuwul/1/edit.

Notice that the green box is acting as if the red box is not even there, rather than “flowing” around it like the text does. This is what floats do: They cause other floated elements and inline content to flow around the float, but other block boxes ignore the float.

The only problem I have with the W3C definition is that it sounds like it’s talking about absolutely posi-tioned elements. So it seems that floats should have a different wording ascribed to them. I prefer to say that floats are taken out of the normal flow in relation to sibling block elements.

Regardless of the explanation, you should be able to see that no matter how far browsers advance, they will never clear floats automatically (as the original question seemed to assume) — because the behaviour of floats is not a bug; it’s a feature.

FLOAT CLEARING METHODS

To round this post out, let’s cover the most popular methods for clearing floats.

clear: both/left/right

The primary way to prevent an element from flowing alongside a floated sibling is to use the clear prop-erty. Any value other than “none” will clear the element that you want to follow the float (rather than bump up against it).

Change my CSS!

As Scott points out in the comments, it looks like there will indeed be an easy way to clear floats, using the contain-floats value for the min-height property. Interesting stuff. I believe this specification is only a month or two old, so I don’t expect browsers to have support for this any time soon. But good to know.

2/3

Page 94: Appliness #9 – December 2012

ABOUT THIS ARTICLE

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

@ImpressiveWebs

ONLINE RESOURCES

Using Absolute Positioning in CSShttp://www.impressivewebs.com/absolute-position-css/

The Difference Between “Block” and “Inline”http://www.impressivewebs.com/difference-block-inline-css/

How Do Browsers Render the Different CSS Border Style Properties?http://www.impressivewebs.com/comparison-css-border-style/

overflow: hidden/auto

The main problem with floats is what you might refer to as the collapsing container, which causes back-ground elements to disappear. In this case, you don’t have a trailing element that you can “clear” to fix this. But instead, you want the parent element to fully contain all the floated children. In this case, at the very least you’ll need to use the overflow property. Using a value of “hidden” or “auto”, the parent will expand to contain all floated children. Although this is probably the easiest way to clear floats, it’s really not recommended, because of the problem of scrollbars appearing or child elements being cut off due to positioning, margins, or CSS3 transforms.

I think the only time I would consider using this one is for a small widget-like box in the page that has floated children (like a tab switcher or something like that), where I know that positioned elements and margins are not going to be a problem.

clearfix

The best method to use to clear floats is the clearfix method. I can’t remember who originally came up with this, but the most updated and optimized syntax that works in all browsers is the one proposed by Nicolas Gallagher and used in HTML5 Boilerplate. Here’s the code:

view plain?.clearfix:before, .clearfix:after { content: “ “; display: table; } .clearfix:after { clear: both; } /* For IE 6/7 only */ .clearfix { *zoom: 1; }

With that in your CSS, all you have to do is add a class of “clearfix” to any element that is “collapsed” due to floated child elements. Again, you could use the overflow method instead, but it’s not universally ideal. I’ve found it causes too many problems in complex layouts.

TO SUM UP

Yes, float clearing is still necessary in modern browsers, and the best method is the clearfix method. But eventually, we want all in-use browsers to support an alternative, more intuitive method for doing CSS layouts, so we don’t have to worry about hacks and workarounds to fix these types of problems.

Post excerpt photo credit: Root beer float from Bigstock.

Page 95: Appliness #9 – December 2012

appliness( DON’T WORRY, BE APPLI

by Maximiliano Firtman

MISSION: IMPOSSIBLE – IPAD MINI DETECTION FOR HTML5AS YOU MAY KNOW, THE IPAD MINI IS A NEW 7.9” VARIANT OF THE IPAD TABLET AND ONE OF THE BIG-GEST QUESTIONS OUT THERE TODAY IS HOW TO DETECT IT USING SERVER-SIDE OR CLIENT-SIDE TECH-NIQUES.

MISSION IMPOSSIBLE?

I have bad news for you: it seems impossible.

Two days ago, I’ve tweeted about the first detected problem: “It is confirmed that the iPad mini User Agent is the same as the iPad 2“. I’ve received literally hundreds of answers saying that user agent sniff-ing is a bad practice, that we should detect features not devices, etc, etc.

Well yes guys, you are right, but it has no direct relationship with the problem. And I need to add the second bad news: there is no client-side technique to make ”feature detection” either.

WHY DO WE NEED TO DETECT THE IPAD MINI IN FIRST PLACE

The iPad mini has no Retina display - the name that Apple gives to high res-olution devices - and it’s an iPad 2 clone in terms of resolution: 768×1024 pixels. The biggest difference is that while iPad 2 is 9.7”; the iPad mini is 7.9”.

Page 96: Appliness #9 – December 2012

While it’s true that the difference between iPad 2 and iPad mini (1.8” or 4.57cm diagonally) is not so big compared to other series (Nexus 7 and Nexus 10 difference is 3”), we need to understand that everything looks 19% smaller on the iPad mini, including text and touch areas. (Update: real demo of this difference)

Ok, you are right; we don’t really need to care about iPad mini vs. iPad 2 in terms of the device itself, but we do need to care about the dpi difference. Designers should want to make some things larger so they can be read properly, or to make touchable areas larger to avoid usability problems.

Second reason is analytics: some companies want to store information about user’s devices to make some decisions and in this case tablet size and factor, or device release date may be something useful. I know this is not a big problem, but it still sounds like an issue for some website and app owners.

HOW TO DETECT A FEATURE OR A DEVICE

There are several mechanisms to make feature and device detection and it’s a long story. I have a full chapter on this topic in the second edition of my book Programming the Mobile Web (available today as a prerelease draft version).

We should always prefer feature detection against device detection; but on some specific situations de-vice detection is the only way to go.

When talking about server-side detection, the User Agent and/or device libraries, such as ScientiaMo-bile’s WURFL is the way to go. The User Agent thing is a mess and there is no simple rule to follow and, when a company like Apple decides to use the same User Agent for all devices, there is no server-side only solution that can help us. In this particular case, all the iPads out there, from the first to fourth gen-eration and the iPad mini uses the same User Agent. The only difference is the iOS version that they have.

I know many of you are thinking: I don’t care about server-side detection, a good practice following RWD - Responsive Web Design - principles is to use media queries or at least JavaScript to detect features. Well, the big bad news appears: there is no way to detect iPad mini unique features (dpi, screen size in inches/cm). Let’s see why.

USING RESOLUTION MEDIA QUERIES

CSS3 Media queries includes a resolution attribute that we can query on. The iPad Mini has a 163 dpi resolution screen while iPad 2 has 132 dpi. Great! We have the solution… well, the resolution attribute is not available con WebKit-based browsers, such as Safari on iOS. No way to use it.

USING DEVICE PIXEL RATIO

After that, we think on a non-standard media query extension: the device pixel ratio. High-resolution iPads expose a 2 value from both media queries and JavaScript for the device pixel ratio. Well, iPad mini and also iPad 2 both expose a value of 1; so we can’t rely on this property neither.

USING INCHES OR CENTIMETERS UNITS

The other solution about dimensions in in (inches) or cm (centimeters). Well, trying to draw a 10 inch ele-ment on the screen, such as in width: 10in; I’ve got same results on both devices (that is, on the iPad mini the div is 19% smaller).

UPDATE: In the CSS3 spec, inches or centimeters units might not match the physical size if the anchor unit is the pixel. Therefore they are useless on these devices.

2/3

Page 97: Appliness #9 – December 2012

ABOUT THIS ARTICLE

Max Firtman is a mobile+web developer, trainer, speaker and writer. He is Nokia Developer Champion, Adobe Community Champion and founder of ITMas-ter Professional Training. He wrote many books, in-cluding “Programming the Mobile Web” published by O’Reilly Media and “jQuery Mobile: Up and Running”. http://www.mobilexweb.com/

@firt

Both iPad 2 and iPad mini exposes same device-width and device-height in inches and centimeters (it’s matching the pixel values) while we know that is completely false. The following media query is true for all the iPads:

only screen and (min-device-width: 8in)

And the iPad mini has a device width smaller than 5.3 inches, so the query should be false in a first quick thought.

And with font size and font adjustment, the results are also exactly the same. There is no special text ad-justment for the iPad mini and it’s using the same values.

If you want to try the media queries values yourself visit mediaqueriestest.com or m.ad.ag from your mo-bile device.

APPLE… WHY?

I know some of you will find some obscure reasons, but the official reason is to reduce iOS fragmentation. From a developer and designer perspective we have only two devices: iPhones (including iPod touch) and iPads. That’s all you need to know from an Apple perspective to design and develop a website or an app. While is not a bad idea in a first thought, the iPad mini has a different screen size and that should be honor by the media queries at least.

To make a final conclusion, the problem is not that we can’t detect iPad mini; the problem is that we can’t detect its unique features, such as density and real dimensions that are important for delivering the best possible experience one ach device using responsive web design techniques.

SOLUTIONS?

People were asking by Twitter how to deal with this. Well, I can only think on some suggestions:

1. Don’t disable zoom ability in the viewport metatag, such as in user-scalable=no.

2. If you have text, offer the user the ability to increase and decrease font size and store the settings in Local Storage or a cookie for next visit. It can be easily implemented using JavaScript and you can change font-size or -webkit-text-size-adjust.

PS: Don’t get me wrong… I’ve tried the iPad mini and I like it; it feels good and the screen is much more useful than other 7” similar tablets.

Page 98: Appliness #9 – December 2012

appliness( DON’T WORRY, BE APPLI

by Holly Schinsky

TUTORIAL: EMBED PHONEGAP AS A SUBVIEW IN YOUR NATIVE IOS APPLICATIONREAD HOW TO SET PHONEGAP AS A WEB “SUBVIEW” OF A NATIVE APPLICATION.

Something cool that many mobile developers (and particularly native developers) might not be aware of at this point, is the option to use PhoneGap (aka Cordova) as a component within your mobile applica-tion, as a web “subview” of a whole native application where you want to render HTML/JS content and/or interact with the PhoneGap APIs. In this webview component (sometimes also referred to as Cleaver), you can do anything a traditional PhoneGap application would do, such as access native features like the camera or contacts etc too. This post will expand the steps here and show you a sample application you could download and try yourself. Note that I am not an Objective-C native programmer, but this is just a simple example to show off the capabilities and create awareness. Feel free to post your application or source if you have used this and would like to share with others.

STEPS TO EMBED CORDOVA WEBVIEW

Below are detailed steps on including PhoneGap/Cordova as a web subview in your native application. At the end of this section I show screenshots from a sample application I made available on my github account for you to try this out yourself or refer to things as needed.

1. Create your base native iOS application in XCode (version 4.5 recom-mended) unless you just plan to add to an existing native application.

In my case I chose to create a new Single View Application in XCode such as the following:

Page 99: Appliness #9 – December 2012

2. Download and extract the Cordova source to a permanent folder location on your hard drive (for example: ~/Documents/Cordova).

NOTE:

3. Close any other Cordova projects and exit XCode (XCode can be quirky, a restart often clears up potential or possible errors).

4. Navigate to the directory where you put the downloaded Cordova source above and copy the Cor-dova.plist file into your native application folder on the file system (at same level as the AppDel-egate files etc, see picture below). Note: you could also use a Cordova.plist from a newly created Cordova application.

You’ll need this for copying Cordova resources into your native application.

2/11

Page 100: Appliness #9 – December 2012

NOTE:

5. Drag and drop the Cordova.plist file into the Project Navigator of Xcode.

6. Choose the radio-button “Create groups for any added folders”, select the Finish button.

7. Go to the downloaded source from the previous step above and locate the CordovaLib.xcodeproj in the CordovaLib sub-folder. Drag and drop the CordovaLib.xcodeproj file into the Project Navi-gator of XCode (at the same level as the .plist file copied in above – again choosing ‘Create groups for any added folders‘).

8. Select CordovaLib.xcodeproj in the Project Navigator.

9. Open the File Inspector with Option-Command-1 or by going to View | Utilities | Show File In-spector.

10. Ensure that it says “Relative to Group” in the File Inspector for the Location drop-down menu simi-lar to below:

11. Select the project icon in the Project Navigator, select your application under “TARGETS” (should have an A next to it), then select the “Build Settings” tab as shown below:

This file contains specific Cordova property settings and plugins required for your application to use Cor-dova.

3/11

Page 101: Appliness #9 – December 2012

Locate the setting for “Other Linker Flags” (under the Linking section) and double-click the value text field to bring up the box to enter the flags -all_load and -Obj-C as shown here:

Select the project icon in the Project Navigator, select your target, then select the “Build Phases” tab.

12. Expand “Link Binaries with Libraries”. Select the “+” button, and add these frameworks (and op-tionally in the Project Navigator, move them under the Frameworks group):

AddressBook.framework

AddressBookUI.framework

AudioToolbox.framework

AVFoundation.framework

CoreLocation.framework

MediaPlayer.framework

QuartzCore.framework

SystemConfiguration.framework

MobileCoreServices.framework

CoreMedia.framework

4/11

Page 102: Appliness #9 – December 2012

Now expand “Target Dependencies”.

Select the “+” button, and add the CordovaLib build product.

13. Expand “Link Binaries with Libraries” again and add libCordova.a.

14. Go to “Xcode Preferences -> Locations -> Derived Data -> Advanced…” and ensure it is set to “Unique”.

15. Go back to Build Settings and locate the Header Search Paths and ensure the following properties are set (including the quotes):

“$(TARGET_BUILD_DIR)/usr/local/lib/include”

“$(OBJROOT)/UninstalledProducts/include”

“$(BUILT_PRODUCTS_DIR)”

5/11

Page 103: Appliness #9 – December 2012

The result should look like the following:

CODE ADDITIONS

To actually use the subview, you need to add the following Objective-C code where you want to include it.

IMPORT THE FOLLOWING HEADER

#import <Cordova/CDVViewController.h>

INSTANTIATE A NEW CDVVIEWCONTROLLER

CDVViewController* viewController = [CDVViewController new];

SET UP THE VIEW FRAME

viewController.view.frame = CGRectMake(0, 0, 320, 480);

LASTLY, ADD TO YOUR VIEW AS A SUBVIEW

[myView addSubview:viewController.view];

You could optionally set the www folder, start page or option to show the splash screen to something other than the default (default folder is www, start page is index.html and splash screen is no) on that CDVViewController as well with the following lines:

viewController.wwwFolderName = @”myfolder”;viewController.startPage = @”mystartpage.html”;viewController.useSplashScreen = YES;

Here’s an example of actually implementing those lines above in my ViewController.m class that is created with a new native XCode Single View project like discussed above (the added code is in the viewDidLoad function):

6/11

Page 104: Appliness #9 – December 2012

#import “ViewController.h”#import <Cordova/CDVViewController.h> @interface ViewController () @end @implementation ViewController - (void)viewDidLoad{ [super viewDidLoad]; CDVViewController* viewController = [CDVViewController new]; viewController.view.frame = CGRectMake(0, 40, 320, 450); [self.view addSubview:viewController.view];} - (void)viewDidUnload{ [super viewDidUnload]; // Release any retained subviews of the main view.} - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{ if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); } else { return YES; }} - (void)dealloc { [super dealloc];}@end

7/11

Page 105: Appliness #9 – December 2012

NOTE:

In my sample application you can see it when you press the Open a new Cordova WebView button. You could choose to add this code wherever you need it, this is just one example for simple illustration.

Since we added the above code to create a new CDVViewController into our main ViewCon-troller, we could reuse this class anywhere in our application and it will automatically include the Cordova subview. In the storyboard file in XCode (the UI environment), you can actually set the class of any given View Controller object to ViewController and you will get a new Cordova WebView subview component automatically due to this code. You can simply set the class to it if it’s not selected already in the Identity Inspector as shown here:

8/11

Page 106: Appliness #9 – December 2012

SAMPLE APPLICATION

In the first screenshot below, the header navigator and tab bar at the bottom (with badge), and the sec-ond view with all the text and controls are actually native iOS controls, whereas the middle embedded view with the button list is an embedded Cordova WebView containing HTML/JS to interact with the native Cordova/PhoneGap APIs to retrieve contacts, use the camera, etc.

If you’re familiar with Storyboarding in XCode for iOS, the Storyboard shows an overview and flow of the application from the native perspective, so you can see the parts which are iOS Native controls versus the other buttons etc that were included from the HTML/JS as part of the Cordova WebView:

9/11

Page 107: Appliness #9 – December 2012

In the next screenshot you can see how we can interact with the Cordova/PhoneGap APIs for native func-tions like grabbing contacts right there inside our native application:

10/1

1

Page 108: Appliness #9 – December 2012

This next view is all native iOS controls (see storyboard), but includes a button to pop up a new view that uses the same ViewController class and will have the embbeded Cordova subview:

And lastly is our next view from the button pop-up that shows how another view will also have the embedded Cordova WebView:

Grab the sample application from my github account and give it a whirl.

I will cover including a Cordova WebView in Android in my next post so stay tuned!

Page 109: Appliness #9 – December 2012

appliness( DON’T WORRY, BE APPLI

by TIm Pietrusky

RESPONSIVE MENU CONCEPTSTIM’S ARTICLE WAS ORIGINALLY PUBLISHED ON CSS-TRICKS.COM.

When it comes to responsive design we are faced with various techniques on how to best handle altering our navigation menus for small screens. The resources seem endless. That’s why I’m going to show you four main concepts and discuss the advantages and disadvantages of all of them.

Three of them are made with pure CSS and one uses a single line of JavaScript.

BEFORE WE START

In the code presented in this article, I don’t use any vendor-prefixes to keep the CSS easier to see and understand. The more complex CSS examples use SCSS. Each example is hosted on CodePen where you can see the compiled CSS if you wish.

All menu concepts in this article are based on this simple HTML structure which I call basic menu. The role attribute is used to specify the particular concept (full-horizontal, select, custom-dropdown and off-canvas).

<nav role=””> <ul> <li><a href=”#”>Stream</a></li> <li><a href=”#”>Lab</a></li> <li><a href=”#”>Projects</a></li> <li><a href=”#”>About</a></li> <li><a href=”#”>Contact</a></li> </ul></nav>

Page 110: Appliness #9 – December 2012

To address small screens I use the same media query on all concepts.

@media screen and (max-width: 44em) {

}

1. FULL HORIZONTAL

This is the most simple approach because you just need to make the list elements full width on small screens.

HTML

<nav role=”full-horizontal”> <ul> <li><a href=”#”>Stream</a></li> <li><a href=”#”>Lab</a></li> <li><a href=”#”>Projects</a></li> <li><a href=”#”>About</a></li> <li><a href=”#”>Contact</a></li> </ul></nav>

CSS

@media screen and (max-width: 44em) { nav[role=”full-horizontal”] { ul > li { width: 100%; } }}

This is what it looks like on a small screen with a custom style.

2/11

Page 111: Appliness #9 – December 2012

ADVANTAGES

•No JavaScript

•No extra HTML

•Simple CSS

DISADVANTAGES

•Reserves too much screen-space

DEMO

On CodePen:

2. SELECT

This concept hides the basic menu on small screens and shows a select menu instead.

To achieve this we need to extend our basic markup and add a select. To get the select working we also add some JavaScript which alters window.location.href when the onchange event on the select occurs.

<nav role=”select”> <!-- basic menu goes here --> <select onchange=”if (this.value) window.location.href = this.value;”> <option value=”#”>Stream</option> <option value=”#”>Lab</option> <option value=”#”>Projects</option> <option value=”#”>About</option> <option value=”#”>Contact</option> </select></nav>

Tap the menu items

3/11

Page 112: Appliness #9 – December 2012

We hide the select on big screens.

nav[role=”select”] { > select { display:none; }}

On small screens, we hide the basic menu and show the select. To help the user recognize that this is a menu we’re also adding a pseudo-element with the text “Menu”.

@media screen and (max-width: 44em) { nav[role=”select”] { ul { display: none; }

select { display: block; width: 100%; }

&:after { position: absolute; content: “Menu”; right: 0; bottom: -1em; } }}

This is what it looks like on a small screen with a custom style.

ADVANTAGES

•Doesn’t need much space

•Uses native controls

DISADVANTAGES

•Needs JavaScript

•Duplicate content

•Select is not styleable in every browser

4/11

Page 113: Appliness #9 – December 2012

DEMO

This demo is best viewed on CodePen.

3. CUSTOM DROPDOWN

This concept hides the basic menu on small screens and shows an input & label (to use the Checkbox Hack) instead. When the user clicks on the label, the basic menu is shown underneath.

<nav role=”custom-dropdown”> <!-- Advanced Checkbox Hack (see description below) --> <!-- basic menu goes here --></nav>

PROBLEM WITH THE CHECKBOX HACK

There are two problems with the default Checkbox Hack:

1. Doesn’t work on mobile Safari (iOS < 6.0). It’s not possible to click the label on iOS < 6.0 to toggle the input due to a bug. The only solution is to add an empty onclick to the label.

2. Doesn’t work on the default Android browser (Android <= 4.1.2). Once upon a time there was a WebKit Adjacent/General Sibling & Pseudo Class Bug which prevented the use of pseudo-classes combined with adjacent (+) or general (~) sibling combinators.

h1 ~ p { color: black; }h1:hover ~ p { color: red; }

This has no effect because the checkbox hack uses the pseudo-class :checked combined with the general sibling. And since this was fixed in WebKit 535.1 (Chrome 13) and the actual WebKit on Android 4.1.2 is 534.30, the normal checkbox hack doesn’t work on any Android device to date.

The best solution is to add a WebKit-only fake animation on the body element.

All stuff combined creates the Advanced Checkbox Hack:

HTML

<!-- Fix for iOS --><input type=”checkbox” id=”menu”><label for=”menu” onclick></label>

CSS

/* Fix for Android */body { -webkit-animation: bugfix infinite 1s; }@-webkit-keyframes bugfix { from { padding: 0; } to { padding: 0; } }

/* default checkbox */input[type=checkbox] { 5/

11

Page 114: Appliness #9 – December 2012

position: absolute; top: -9999px; left: -9999px;}

label { cursor: pointer; user-select: none;}

Reference: Advanced Checkbox Hack

For large screens, we hide the label:

CSS

nav[role=”custom-dropdown”] { label { display: none; }}

For small screens, we hide the basic menu and show the label. To help the user recognize that this is a menu we’re also adding a pseudo-element with the text “≡” (converted to “\2261” to use it as content on the pseudo-element) to the label. When the user clicks on the input, the basic menu gets shown and the list elements are expanded to full width.

@media screen and (max-width: 44em) { nav[role=”custom-dropdown”] { ul { display: none; height: 100%; }

label { position: relative; display: block; width: 100%; }

label:after { position: absolute; content: “\2261”; } input:checked ~ ul { display: block; > li { width: 100%; } } }}

6/11

Page 115: Appliness #9 – December 2012

This is what the menu looks like on a small screen with a custom style.

CLOSED

OPEN

ADVANTAGES

•Doesn’t need much space when closed

•Custom styling

•No JavaScript

DISADVANTAGES

•Bad semantics (input / label)

•Extra HTML

7/11

Page 116: Appliness #9 – December 2012

DEMO

On CodePen:

4. OFF CANVAS

This concept hides the basic menu on small screens and shows a HTML input & label (to use the Advanced Checkbox Hack, see 3. Custom Dropdown for more infos) instead. When the user clicks on the label, the basic menu flies in from the left and the content moves to the right – the screen gets divided: menu ~80 % and content ~20 % (depends on resolution and css units).

HTML

<input type=”checkbox” id=”menu”><label for=”menu” onclick></label>

<!-- basic menu goes here -->

<div class=”content”> <!-- content goes here --></div>

On large screens, we hide the label.

CSS

label { position: absolute; left: 0; display: none;}

Tap the submenu

8/11

Page 117: Appliness #9 – December 2012

On small screens, we hide the basic menu outside the viewport and show the label / input. To hide the menu we specify a width ($menu_width) and add a negative position to it. To help the user recognize that this is a menu we’re also adding a pseudo-element with the text “≡” (converted to “\2261” to use it as content on the pseudo-element) to the label.

When the user clicks on the input, the basic menu flies in from the left and the content moves to the right.

@media screen and (max-width: 44em) { $menu_width: 20em;

body { overflow-x: hidden; } nav[role=”off-canvas”] { position: absolute; left: -$menu_width; width: $menu_width; ul > li { width: 100%; } }

label { display: block; }

label:after { position: absolute; content: “\2261”; }

input:checked ~ nav[role=”off-canvas”] { left: 0; }

input:checked ~ .content { margin-left: $menu_width + .5em; margin-right: -($menu_width + .5em); }}

This is what the menu looks like on a small screen with a custom style.

CLOSED

9/11

Page 118: Appliness #9 – December 2012

OPEN

ADVANTAGES

•Doesn’t need much space when closed

•Custom styling

•No JavaScript

•Convention from Facebook / Google+ app

DISADVANTAGES

•Bad semantics (input / label)

•Extra HTML

•Absolute position to the body = Feels like fixed position

DEMO

On CodePen:Tap the submenu

10/1

1

Page 119: Appliness #9 – December 2012

ABOUT THIS ARTICLE

I’m Tim Pietrusky, a 27 years old Web Craftsman from Frankfurt (Main), Germany. My time is divided into programming, writing and thinking about all kinds of web related stuff, because I freaking love what I do.

http://timpietrusky.com/

@TimPietrusky

DOES IT WORK ON IE?

All of the techniques used above have one goal: Create responsive menus for modern browsers! And be-cause there is no IE 8 or lower on any mobile device we don’t need to worry about it.

RELATED POSTS

•Responsive Data Table Roundup

•Responsive Data Tables

Page 120: Appliness #9 – December 2012

appliness( DON’T WORRY, BE APPLI

by Nicholas C. Zakas

JAVASCRIPT APIS YOU’VE NEVER HEARD OF (AND SOME YOU HAVE)CLICK TO SEE NICHOLAS’S ORIGINAL BLOG POST.

The number of JavaScript APIs has exploded over the years, with a small subset of those APIs getting all the attention. While developers feverishly work on Web sockets and canvas, it’s easy to overlook some smaller and quite useful APIs. This talk uncovers the “uncool” JavaScript APIs that most people have never heard of and yet are widely supported by today’s browsers. You’ll learn tips and tricks for working with the DOM and other types of data that you can use today.

Nicholas C. Zakas is a front-end consultant, author and speaker. He worked at Yahoo! for almost five years, where he was front-end tech lead for the Yahoo! homepage and a contributor to the YUI library. He is the author of Maintainable JavaScript (O’Reilly, 2012), Professional JavaScript for Developers (Wrox, 2012), High Performance JavaScript (O’Reilly, 20120), and Professional Ajax (Wrox, 2007).

Disclaimer: Any viewpoints and opinions expressed in this article are those of Nicholas C. Zakas and do not, in any way, reflect those of my employer, my colleagues, Wrox Publishing, O’Reilly Publishing, or anyone else. I speak only for myself,

not for them.

http://www.nczonline.net

@slicknet

Page 121: Appliness #9 – December 2012

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

appliness( HELTER SKELTER NEWS

How promises workvia Kris Kowal

Reducing HTTP Re-quests for Images using CSS Spritesvia Peter Keating

Variable declarations: three rules you can breakvia Dr. Axel Rauschmayer

Getting Started with Parsevia Tilo Mitra

CSS Things That Don’t Occupy Spacevia Louis Lazaris

Defer ALL The Thingsvia James Socol

Stairway Navigation (A jQuery Plugin?)via Chris Coyier

Compiling to JavaScript: What, Why, and How?via Andre Rieussec

Testing Globalization Support in PhoneGap 2.2by Ray Camden

Page 122: Appliness #9 – December 2012

appliness( HELTER SKELTER NEWS

MORE NEWS ON REMOTESYNTHESIS.COM

IE10 CSS Hacksvia Louis Lazaris

The state of CSS 3D trans-formsvia Keith Clark

Building A Relation-ship Between CSS & JavaScriptvia Tim Wright

Responsive CSS Time-line with 3D Effectvia Mary Lou

Learning Principles for Improving Your CSSvia Hugo Giraudel

Code smells in CSSvia Harry Roberts

A Few New Things Coming To JavaS-criptvia Addy Osmani

Go Node Without Codevia Brian Rinaldi

Page 123: Appliness #9 – December 2012

appliness( THE TEAM

Contribute and join ApplinessAppliness is a free digital magazine edited by passionate web developers. We are looking for contributors. Con-tact us and join the adventure. You’ll find on our website appliness.com a feedback form. You can also follow us on twitter, facebook and Google+.

M I C H A E L CHAIZE

Michaël Chaize is a Developer Evangelist at Adobe where he focuses on Rich Internet Application and Mo-bile 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 de-velopments of effective, efficient, engaging, easy to learn and error free applications. Before joining Ado-be, Michael founded a software company and taught RIA languages such as Flex and PHP in IT engineering schools. He’s the editor in chief of Appliness.

P I O T R WALCZYSZYN

Piotr Walczyszyn is a technology geek living in War-saw, Poland, where he was born. out of.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 Applica-tions) anymore, and he thinks this phrase has become almost passe although its main concepts have not.

PA U L HUNT

Paul has been working at Adobe Systems foundry since January 2009 helping to develop typefaces at every level of production from conceptualizing and drawing to OpenType programming, exporting and beta testing.

B R I A N RINALDI

Brian Rinaldi is as a Content and Community Man-ager for the Adobe Developer Center team, where he helps drive content strategy for HTML5 and JavaS-cript developer content.

Brian blogs regularly at http://remotesynthesis.co-mand and is a unreformed twitter addict.

D M I T R Y BARANOVSKIY

Dmitry is a Sydney-based web developer interested in HTML, CSS, JavaScript, XSLT and SVG. Currently he is working at Adobe as a Senior Computer Scientist. He’s the creator of the JavaScript library “Raphael”.

A N D R E W T R I C E

Andrew Trice is a Technical Evangelist with Adobe Systems. Andrew brings to the table more than a de-cade 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 de-velopment, realtime data systems, GIS, and data visu-alization.

M A I L E VALENTINE

Maile is the assistant editor for Appliness magazine and has worked with Adobe both as an employee and consultant for 8 years now. Maile started with Adobe on the Technical Marketing team as a technical train-er for the Adobe LiveCycle Enterprise Suite (most re-cently Adobe Digital Enterprise Platform).

She then went on to work with the Adobe Enterprise Evangelist team to support great Flex developer re-sources 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.

G R E G WILSON

Greg is a Developer Evangelist at Adobe Systems fo-cusing 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 large-scale applications at Verizon, Motorola, NASA/Boe-ing and others.

CHRISTOPHE COENRAETS

Christophe is a Developer Evangelist for Adobe where he focuses on Web Standards, Mobile, and Rich HTML Applications with a special focus on Enterprise Inte-gration. In this role, Christophe has helped some of the largest financial services companies design, archi-tect and implement some of their most mission criti-cal 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 com-pany’s J2EE application server. Before joining Macro-media, 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.

H O L L Y SCHINSKY

Holly is a Developer Evangelist at Adobe Systems and has been doing software development since 1996 with experience working for various Fortune 500 compa-nies to startup. Holly’s experience is primarily in OO languages, but she thrives on constantly learning new things & is always up for a challenge.