appliness 8 November

yrekazzyzxamuckInternet και Εφαρμογές Web

4 Δεκ 2013 (πριν από 3 χρόνια και 10 μήνες)

189 εμφανίσεις

Picture by Elle Osmani
app
liness
(
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 8TH ISSUE OF THIS MAGAZINE.
TABLE OF CONTENTS
NEWS ABOUT HTML
AND JAVASCRIPT
by Brian Rinaldi
HELTER SKELTER NEWS
NAVIGATION GUIDE
READ 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 PREVIOUS
ARTICLE
DISPLAY THE TABLE OF

CONTENTS
VISUALLY BROWSE ALL
THE ARTICLES
TUTORIALS
8 TIPS FOR ANGULAR.
JS BEGINNERS
by Sudhanshu Raheja
JAVASCRIPT:
OPERATORS
by Dmitry Baranovskiy
DELAY INITIALIZATION
WITH JQUERY DELEGATION
by Joe Zimmerman
APPLE PUSH
NOTIFICATIONS WITH
PHONEGAP

by Holly Schinsky
DOES JAVASCRIPT NEED
CLASSES?
by Nicholas Zakas
NODE.JS, REQUIRE
AND EXPORTS

by Karl Seguin
INTERVIEW
ADDY OSMANI - THE MODERN YEOMAN

Exclusive interview by Maile Valentine
EMBRACE THE STATIC
WEB WITH PUNCH
by Lakshan Perera
SHOWCASE
COMPLETURE
built with PhoneGap
NATIVE SCROLLING
IN JQUERY MOBILE/
PHONEGAP APPLICATIONS

by Piotr Walczyszyn
NODE.JS, MODULE.
EXPORTS AND
ORGANIZING
EXPRESS.JS ROUTES

by Karl Seguin
PHONEGAP, APPLE
REJECTIONS & UI/UX
GUIDELINES

by Andrew Trice
LIBRARY OF THE MONTH
INTERVIEW
JEREMIE PATONNIER - CSS & SVG EXPERT

Exclusive interview by Vincent Hardy
INTERVIEW
PAUL D. HUNT - FONT DESIGNER
Exclusive interview by Michaël Chaize
WHY ARE
PREPROCESSORS SO
DIVISE?

by Kianosh Pourian
HACKING JAVASCRIPT’S
FORMAT PARAMETERS
WITH FUNCTION.APPLY()

by Jeremy Kahn
USING YEOMAN WITH
ANGULAR.JS
by Brian Ford
CHEAT SHEET
5 HTML5 APIS YOU
DIDN4T KNOW EXISTED
by David Walsh
DON’T WORRY, BE APPLI
app
liness
by Sudhanshu
Raheja
(
8 TIPS FOR ANGULAR.JS BEGINNERS
WE STARTED WORKING WITH ANGULAR.JS RECENTLY AND, AFTER SPENDING A FEW DAYS ON IT, I RE
-
ALISED THAT THERE WAS A BIG NEED FOR BEGINNER TUTORIALS ON IT. I’VE TRIED TO DOCUMENT
SOME OF THE THINGS YOU MIGHT NEED ON DAY 1.
#1
Yes, it’s really worth it. So do spend a little extra time.
Here’s an example of the issues you would face:
Discussion from StackOverflow: http://stackoverflow.com/questions/10486769/cannot-get-to-rootscope
Thanks, it makes perfect sense, but how did you know that? Was it in the docs? – Malvolio May 7 at 21:55
@Mavolio No, he is one the 3 core developers. – ChrisOdney Jun 6 at 19:36
The documentation sucks and you have to assume stuff. But there is light at the end of the tunnel.
If you need resources, you should try out the following:
a. Run through the videos first – this should get your hooked. The fol
-
lowing two are essential
- http://www.youtube.com/watch?v=WuiHuZq_cg4
THE DOCUMENTATION STILL SUCKS SO
IT’S OKAY IF YOU’RE TAKING MORE TIME.
- http://www.youtube.com/watch?v=IRelx4-ISbs
b. Run through the tutorial – http://docs.angularjs.org/tutorial/step_00
c. Run through the concepts – http://docs.angularjs.org/guide
d. Finally, keep this open – http://docs.angularjs.org/api/ – it won’t help much other than just
to remember what some function did.
e. Read this blog post – http://deansofer.com/posts/view/14/AngularJs-Tips-and-Tricks-UP
-
DATED
f. If it did look interesting, add AngularUI to your project – https://github.com/angular-ui/
angular-ui/
g. Go and join the AngularJS google group. It’s quite active.
#2
I have divided the code into two files. The first is the app.js and the second is the controllers.
App.js
contains code for setting up routes,
app.factory
functions and
app.run
to setup
$root
-
Scope
.
Controllers.js
contains all controllers so far.
#3
I do this in the
App.js
file:
var
app = angular.module(
‘beta’
, [],
function
($routeProvider, $locationPro
vider) {
$routeProvider.when(‘/home’, {
templateUrl: ‘/partials/home’,
controller: HomeController
});

// When you put /home, it also automatically handles /home/ as well
$routeProvider.when(‘/login’, {
templateUrl: ‘/partials/login’,
controller: LoginController
});
$routeProvider.otherwise( { redirectTo: ‘/login’} );


// configure html5 to get links working

// If you don’t do this, you URLs will be base.com/#/home rather than base.
com/home
$locationProvider.html5Mode(true);
});
HOW TO DIVIDE CODE
HOW TO INITIALIZE THE APP
2/5
#4
This is, again, done in the
app.js
file.
app.factory(
‘db’
,
function
() {

var
items = [];


var
mod
if
y = {};

var
mod
if
y.addItem =
function
(item) {
items.push(item);

return
‘added item’;
};

var
mod
if
y.getItems =
function
() {

return
items;
}

return
mod
if
y;
// returning this is very important
});
now, in your controller, you can access these as follows:
function
MainCtrl =
function
($scope, db) {
$scope.save =
function
() {
db.addItem(
‘hello’
);
console.log( db.getItems() );
};
}
#5
This might seem a little stupid for people who have been doing this for a long time, but, well I stumbled
on this, so this makes the cut.
Basically, what this means is that whenever you’re trying to test your controller to try out something new,
don’t try this:
function
MainCtrl =
function
($scope, db) {
db.addItem(
‘hello’
);
}
This won’t work for obvious reasons. What you need to do is this:
function
MainCtrl =
function
($scope, db) {
$scope.save =
function
() {
console.log( db.addItem(
‘hello’
) );
}
}
CREATE A SET OF FUNCTIONS THAT YOU
CAN USE
CONTROLLERS ARE JUST FOR DEFINING
THINGS
3/5
and now to run the save function, go to JADE and add:
input(type=
’submit’
, name=
’submit’
, value=
’Submit’
, ng-click=’save()’)
Now open the form, click on submit and check out console.log.
#6
The
$rootScope
is a global, which means that anything you add here, automatically becomes available
in
$scope
in all controller. Nice eh!
To set it up, you need to do something like this (I do it in app.js):
app.run(
function
($rootScope) {
$rootScope.hello =
function
() {
console.log(
‘hello’
);
}
});
This should now be available in controllers:
function
MainCtrl =
function
($scope) {
$scope.save =
function
() {
$scope.hello();
}
};
#7
To use the validation which comes by default with Angular, you need to follow the following steps:
a. give a “name” to your form e.g. <form name=”loginForm”>
b. mark all required input boxes as required e.g. <input type=’email’ required />
c. to turn on say email validation, you need to set type=’email’
d. check if the form is validating or not by checking loginForm.$invalid. To check this inside
your controller, do $scope.loginForm.$invalid
DEFINE FUNCTIONS IN THE $ROOTSCOPE
FORM VALIDATION
4/5
ABOUT THIS ARTICLE
Sudhanshu Raheja is an entrepreneur based out of
Pune, India. He founded Vercingetorix Technologies
(http://vxtindia.com), a consulting firm which part
-
ners with brands to define and execute their mobile
strategy.

http://vxtindia.com/
@sudhanshuraheja
Angular JS
http://angularjs.org/
Vercingetorix Technologies on Facebook
https://www.facebook.com/vercingetorixtechnologies
Vercingetorix Technologies’ Portfolio
http://vxtindia.com/portfolio
ONLINE RESOURCES
#8
If you have defined ng-app in the HTML tag, and have defined an ng-view in the body somewhere. How
-
ever, you want to keep the menu outside ng-view and still want to have access to it programatically to
change menu based the fact that the user is logged in or not, you can define a
ng-controller
on the
menu and make it work like a normal controller.
Another thing I did was to put my menu in
$rootScope
so that each controller can mark which menu
should be used and which one is active.
HANDLING THE MENU VIA
NG-CONTROLLER
by Dmitry Baranovskiy
DON’T WORRY, BE APPLI
(
liness
app
JAVASCRIPT: OPERATORS
IN THE PREVIOUS ARTICLE I TALKED ABOUT TYPES AND TYPE COERCION IN JAVASCRIPT. IN THIS ONE
I WANT TO TALK MORE ABOUT HOW THIS COERCION APPLIES TO JAVASCRIPT OPERATORS. LETS GO
OVER SIX MAJOR OPERATORS AND LOOK AT HOW THEY WORK.
TYPEOF
The
typeof
operator returns a string representation of the type of the passed expression. There are two
major points to note:

Unresolvable references will produce “
undefined
”, i.e.
typeof
a will return “
undefined
” if vari
-
able
a
was not declared.

typeof
lies in two cases for
null
and for
function () {}
.
Apart from this, operator works pretty much as a lookup table:
Type of expression Result
Undefined “undefined”
Null “object”*
Boolean “boolean”
Number “number”
String “string”
Object, that can’t be invoked “object”
Object, that can be invoked “function”*
I marked with “*” two places where operator is misleading: type of null is Null and the actual type of any
function is Object.
SUBTRACTION
Converts both arguments to number.
“8” - true
is converted to
8 - 1
. Very simple, indeed. Don’t
expect the same from addition :)
ADDITION
Addition is one of the trickiest operators in JavaScript. Lets see what is going on when you write
a + b
:
1.
Both arguments are converted to primitives. Lets call them A and B.
2.
If any of primitives is a String, concatenate A and B as strings.
3.
Otherwise compare A and B as numbers.
For example:
//EXAMPLE
8 >
“5”
:: 8 > 5 :: true;
8 > true :: 8 > 1 :: true;
“8”
>
“18”
:: true;
LESS THAN
In contrast to the addition operator, the less-than operator compares arguments as strings only if both of
them are strings. To put it more formally, here are the steps:
1.
Both arguments are converted to primitives. Lets call them A and B.
2.
If both of primitives are Strings, compare A and B as strings.
3.
Otherwise compare A and B as numbers.
For example:
8 >
“5”
:: 8 > 5 :: true;
8 > true :: 8 > 1 :: true;
“8”
>
“18”
:: true;
2/3
STRICT EQUALS
The favourite operator of many, also known as triple equal (===) does things in a very simple way: checks
if the arguments are of the same type and if they are, checks if they are equal. His little brother has a little
bit more complicated character.
EQUALS
Ok, here it comes, the most hated operator of the language. According to the spec it works like so:
1. First check for types, if they are the same, apply strict equals.
2. If both arguments are either
null
or
undefined
, return
true
.
3. If one of them is String and the other is Number, convert both to Number and apply strict equals.
4. If one of them is Boolean, convert it to Number and go to 1.
5. If one of them is String or Number and the other one is Object, convert object into primitive and go
to 1.
6. Return
false
.
This basically means that equals works like less-than, when the types of the arguments are different and
like strict equals, when types are the same. The easy way to remember: when the types are different it
converts both arguments into primitives, then into numbers, unless they both are strings. Oh, and
null
== undefined
is
true
.
8 ==
“5”
:: 8 == 5 :: false;
1 == true :: 1 == 1 :: true;
0 == “” :: 0 == 0 :: true;
0 ==
“0”
:: 0 == 0 :: true;
“” ==
“0”
:: false;
“1000”
==
“1e3”
:: false;
1000 ==
“1e3”
:: true;
5 == {valueOf:
function
() {
return
5; }} :: 5 == 5 :: true;

These are not all the operators, but certainly the most tricky ones.
by Joe Zimmerman
liness
DON’T WORRY, BE APPLI
(
app
DELAY INITIALIZATION WITH
JQUERY DELEGATION
AS THE INTERNET FILLS WITH MORE AND MORE JAVASCRIPT CODE, WE NEED TO BECOME MORE AND
MORE AWARE OF THE IMPACT OF OUR CODE HAS ON PERFORMANCE. ONE OF THE BIG PAIN POINTS
CAN COME FROM ALL OF YOUR CODE BEING INITIALIZED AND LOADED DURING JQUERY.READY() OR
(IF YOU’RE A GOOD BOY WHO PUTS ALL THE CODE AT THE END OF THE DOCUMENT) RIGHT AWAY. WE
CAN DELAY SOME INITIALIZATION UNTIL LATER, RIGHT?
EVENT DELEGATION
For a while now, jQuery has had event delegation. If you know what event delega
-
tion is and how it works, go ahead and skip to the next section. But, for those of you
who don’t know, here’s a little introductory course.
Normally you would attach an event listener directly to an element, and let the han
-
dler go from there. Generally there is absolutely nothing wrong with this, but if the
elements that you wish to attach event listeners to are dynamic (they’re constantly
being created and/or deleted), this can be a hassle. Another time this can be “bad”
is when there are many, many elements to attach to, in which case it’s just slow.
Event delegation was designed for these situations.
The premise behind event delegation is pretty much the opposite of real-
world delegation. Rather than delegating things to those below us, we del
-
egate to elements higher in the hierarchy. Sometimes we even delegate all
the way up to the CEO (
document
). Let’s take a look at a tiny code sample
and walk through it to explain.
// Normal
$(‘.elements’).on(
‘click’
,
function
() {

// Do Something
});

// Delegation
$(document).on(
‘click’
, ‘.elements’,
function
() {

// Do Something
});
With delegation, we attach the listener to an element higher in the hierarchy (
document
in this case).
Then we add another argument to the call to on that specifies a selector that we need to match. Other
than that, it’s exactly the same as the normal event listener.
Here’s how it works:
1.
The
document
listens for click events. Any click that happens on the page will
bubble
up to the
document (unless it was stopped by another event handler).
2.
When the
document
hears a click event it checks to see if the event happened on an element that
matches the selector we passed in (‘.elements’ in this case).
3.
If it matches, it fires the event handler.
It’s that simple. One of the best parts is that the
document
is created immediately, so you can attach
listeners to it within the head of the document and these will still work. If you want to learn more about
event delegation, look
here
.
DELAYED INITIALIZATION
Many times the delayed initialization works pretty well when working with jQuery plugins. The best way
I can explain this concept is through examples. I’ll show two examples of initializing plugins that demon
-
strate a few of the possible hitches you may run into and how to work with them.
THE LIGHTBOX
This first example utilizes the
jQuery lightBox plugin
, which may not be the best plugin, but it works for
my example. This plugin attaches itself to links to images, and then when you click on the link, instead of
just following the link, it creates a modal box with the image contained inside it. If you are using this with
a large gallery or you are using
infinite scrolling
to load more images in dynamically, the normal initializa
-
tion might not be the best bet for you.
2/5
Try this:
We delegate a click event listener on the
document
to limit the amount of code that runs right away. This
delegation makes sure we don’t set the plugin up until we need it and only on the elements that need
it at the moment. So, when a gallery link is clicked, we initialize the lightbox plugin on that one link. We
need to trigger a new click event on it right away so that lightbox will respond to the click. Then we need
to prevent the default action so that we don’t follow the link to a different page. The nice thing about the
lightbox plugin for this example is that it automatically prevents bubbling, so once the lightbox plugin
is initialized on a link, this delegated event handler will never run for that link again. If we weren’t using
JSFiddle, you’d see that ‘init’ is only logged the first time that you click an image.
This technique has some pros and cons.
Pros:

Really low amount of initial overhead computation.

We don’t need to wait for DOM ready to set up the event listeners

Initialize only the elements you need when you need it.

Works for dynamically added content without any additional work.
Cons:

The lightbox must be set up when you click, so there could be a delay between the click and the reac
-
tion to the click. This is generally unnoticeable.

There may be other things that prevent the delegation from reaching the
document
and there is a bit
of overhead associated with bubbling all the way up to the
document
.

A wee bit more code to write.
3/5
THE DATE PICKER
This example uses
jQuery UI’s Date Picker Widget
. It was also taken directly from
Elijah Manor’s post
,
which was the inspiration of this post. We handle things slightly differently this time.
You’ll notice a few distinct differences in implementation between this example and the lightBox example.
1.
We use “:not(.hasDatePicker)” in the selector. Date Picker assigns this class to an element that the
widget has already been initialized on, so we can use that to make sure we don’t initialize the Date
Picker on an element that it has already been initialized on. This is nice because the Date Picker
doesn’t prevent bubbling like the lightBox did, so we need some other way to know not to initialize
the element. What’s also nice is that we can use this inefficient selector because it isn’t scanning the
document for this selector, it’s only comparing the element we have to the selector.
2.
We’re using a toastr library instead of console so you can actually see when it’s initialized and not ini
-
tialized. This of course, doesn’t really matter in real apps.
3.
We don’t need to trigger a focus event again. The Date Picker is smart enough to know that it should
show because its input is in focus already.
4.
We don’t need to prevent the default action. This is because nothing happens by default when some
-
thing is focused.
4/5
ABOUT THIS ARTICLE
Joe Zimmerman has been doing web develop
-
ment 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 cool
-
est inventions ever. In college he was introduced
to real JavaScript, starting his full addiction. Now
his addiction pushes him to continuously learn
more and spread the knowledge to the internet.

http://www.joezimjs.com/
@JoeZimJS
jQuery
http://jquery.com/
jQuery Lightbox Plugin
http://leandrovieira.com/projects/jquery/lightbox/
jQuery Datepicker
http://jqueryui.com/datepicker/
ONLINE RESOURCES
PREVENTING RE-INITIALIZATION
That first point above is one of the key points that you’ll have to think about each time you attempt to
delay initialization like this. You have to find a way to make sure that the initialization doesn’t happen mul
-
tiple times. In the first example, lightBox’s prevention of bubbling did that for us. With the Date Picker,
we had to check for a class that it adds. For other plugins, you may have to wrap the whole event handler
in an
if
statement that checks for the initialization state somehow. Some plugins do this themselves,
so you can call the initializer all you want and it won’t matter, but I wouldn’t count on it unless you read
through the code yourself.
CONCLUSION
Overall, it’s pretty simple to delay initialization of many jQuery plugins and other JavaScript code. In fact,
just converting to delegation for many of your event listeners prevents a lot of overhead and initialization
code from running. Go out and make your JavaScript faster today! God bless and happy coding.
J E R E MI E

PATONNIER
CSS & SVG EXPERT
EXCLUSIVE INTERVIEW
© Guy Lerat
1/5
HELLO JÉRÉMIE. CAN YOU TELL US WHO YOU ARE, WHAT YOU DO AND WHY YOU
ATTENDED “THE GRAPHICAL WEB” CONFERENCE? WHAT’S YOU FAVORITE WORKING
ENVIRONMENT?
Hello, my name is Jérémie Patonnier. I’m a web consultant specialized in front-end design
and development for the French web company named
Clever Age
. I attended “The
Graphical Web” conference to have the opportunity to meet the people working on the
next generation of graphical web technologies.
My working environnement is made of 4 parts : A MacBook Pro
(which is amazingly comfy
but with the power of a UNIX bash when it’s necessary)
, Firefox as my primary web browser
(for development as well as for casual browsing)
, A good text editor
(Sublime Text 2 right
now, but I change quite often)
and the Adobe CS Suite for all my graphical work
(mainly
Photoshop and Illustrator).
WITH BOTH YOUR SVG AND CSS HATS ON, WHAT DO YOU THINK OF THE CURRENT
CONVERGENCE BETWEEN THE TWO LANGUAGES ABOUT FILTERS, EFFECTS, ETC?
I’m very pleased to see that SVG and CSS features are converging. It’s very exciting to see
some SVG specific features moving to CSS because it means it will be soon possible to use
them with HTML. Transformation where the first move and we can see how eager the web
designers and developers are to use it. Filters, Masking, Clipping, etc... are coming as well
into CSS and I wish things were moving faster. However, it’s already very fast and it requires
time to learn all of this. On the other side of the technology, I’m also very pleased to see all
the power of CSS Text & Fonts coming to SVG as well as an harmonization of the syntax of
both languages in favor of CSS.
ARE CSS AND SVG CONVERGING ENOUGH?
I think so. Even if there is still some important gap such as CSS Animations vs SVG Animations,
it’s moving the right way. As an “old” web author, I remember back in 2000 when we get
stuck with almost only one browser. In comparison, today things are moving fast and smooth
on many points. Of course, nothing is perfect and some people would see things moving
faster but as I say, I thinks it’s moving the right way. By “the right way” I mean : technologies
evolved in a very author friendly way and browsers implement things fast, allowing us to
deliver some very impressive web sites (and apps) to the end users.
SVG IS STILL RARE IN TOP400 WEB SITES, WHAT’S MISSING?
Well, I think SVG has suffered from two big problems: first, in its early days SVG was not very
well supported among browsers and at the same time Flash has evolved very quickly pushing
SVG in the shadow. Even if things are changing, IE8 is still a problem to a wider adoption
of SVG. Second, very few designers had used SVG so there is very few SVG “eye candy”
image out there. As a consequence many designers think of SVG as a “technical” image
format. This perception increased when, a few years ago, Adobe acquired Macromedia and
drop active support on SVG in favor of Flash... but it seams the wind is changing now. It is
2/5
worth noticing that the uprising of the
Raphael
library has helped a lot in the revival of SVG
and we start to see more and more SVG in modern Web design. Now, if we want to see
more SVG in the top400 web sites, I think it’s missing only 2 things : good documentation
(Mozilla as well as the W3C are working on this) and some aggressive evangelism about this
technology and the way it can be mixed with other web technologies.
HOW DO YOU USE CSS TODAY? WHAT IS THE MOST IMPORTANT OR MORE USEFUL PART
OF CSS FOR YOUR ACTIVITY?
Today, I’m using CSS without thinking about it. It’s now common practice for me and my
company to use CSS to design web sites as well as web apps. Our core use of CSS is arround
layout where we are actively using grid systems (we built our own based on the
blueprint
framework
and we are currently switching to a new grid system built on top of
Compass
).
We also make an extend use of the text and font abilities (
http://typographisme.net
) as well
as Media Queries.
© CheekFille
3/5
OUTSIDE OF YOUR “PRO” ACTIVITY, WHAT CURRENT CSS CAPABILITY ARE YOU PERSONALLY
MOST ENTHUSED ABOUT USING?
In my opinion, the best is yet to come. I’m eager to see all the new layout capacity because
it will help to solve hard problems we all face every day. But once this is done, I’m higly
excited by 3 new spec proposal :
CSS Exclusions, CSS Filters and CSS Compositing and
Blending
.
I come from the print industry so I dream of what CSS Exclusions bring for years. Having a
text flowing around a shape opens so much graphical oportunity for web designers! Filters
are also a power house, especially custom filters based on shaders that will allow to bend
any HTML element. Combined with the Compositing and blending proposal it just blows
my mind, it’s like having the power of Photoshop in real time in my browser!
HOW DO YOU THINK THE CSS WORKING GROUP IS ADRESSING COMPLEX LAYOUTS WITH
ITS CURRENT LAYOUT PROPOSALS (FLEXBOX, GRIDS, REGIONS, EXCLUSIONS, ETC.)?
WHAT ELSE DO YOU NEED IN YOUR PRODUCTION WORK?
The combination of Flexbox, Grids and Regions allows to solve all common problems
we have with layout. More important, those three tools will allow web developer to do
something they expect since the early days of CSS 2.0: being able to build layout independent
from the HTML flow order. Once the layout problems will be solved, the next big step in
our production work will be all the special effects. This includes animations (that must
be rationalized), control over the visual text flow (as I said previously, I have dreamed of
exclusion shapes for years) and all type of filters (basic filters but also blending, compositing,
clipping and masking).
There are also some needs on the JS part such as a convinient way to use SVG in Canvas
and vice versa and to properly mix audio and video with SVG.
WHAT IS THE MOST DIFFICULT DESIGN PROBLEM WITH YOUR CURRENT WEB PLATFORM
WORK? HOW DO YOU SOLVE IT? POLYFILLS?
The biggest issue I face is interoperability... on all technologies. Most of the time, I handle
HTML/CSS issue by using the “progressive enhancement” and “graceful degradation”
principle. SVG and JS are a bit more tricky and I usually rely on common framework such as
Raphael and jQuery. Finally, I only use polyfills for cutting edge technologies. For example
if I want to use browsers DB, I use a polyfill to mimic indexedDB on platforms that support
only legacy Web SQL. By the way, CSS vendor prefix is a no brainer for me. I make an
extensive use of CSS preprocessor (LESS or SASS) to completely avoid this problem.
MORE GENERALLY, WHAT DO YOU EXPECT FROM THE FUTURE OF CSS?
As the browsers become more and more powerfull, CSS can reach some new places
unreachable a few years ago. For example, there is still big discussion about selectors
and the opportunity to select parent node from a given node. CSS variables are also
4/5
something really interesting to solve some maintenance issues for web developers. In a
more prospective way, I wish for a better text line break algorithm in order to have nicer text
rendering. Advanced visual effects are also something really appealing. The big challenge
in the upcoming year for CSS will be to find a way to bring all of this to authors (developer
and designer) in a way that remain as easy as it is today to use CSS. To achieve that, I urge
web designers and web developers to get involved with browser vendors, through W3C
or through events like “
The Graphical Web
” or “
Test The Web Forward
”. It’s good for web
developers because it allows them to better understand what’s at stake under the hood
and it’s good for browser vendors because they desperately need feedback “from the
battle field”. The future is full of promises and I look forward to it.
YOU ATTENDED TEST THE WEB FORWARD IN PARIS? WHAT DO YOU THINK OF IT? ARE
WEB STANDARDS INTEROPERABLE ENOUGH?
Yes, I was there. This is a great event that is really helpfull for everyone who want to be
involved in building a better Web. Interoperability is the biggest issue on the Web and is
the main source of problems when someone is building a Web site. Writing tests that will
be used by browser vendors to make sure their browsers work as we expect them to is
awesome. It’s maybe the easiest way for web developers to make a big difference in the
future of the Web. This is a direct contribution to the standardization effort and it’s also a
way to better understand the interoperability issues of web technologies.
ANYTHING YOU WANT TO ADD?
Just a last word to spread about my main commitment to the open web technologies.
Those technologies become more and more complex so it’s really important to have good
documentation about those technologies. This documentation is necessary for beginner
as well as for experienced developers. If you find a useful technique, if you find clever
workaround, if you find a way to make clearer the way a property, an attribute or a tag
works, for example, please share it. At least write it on your blog but if you want to be part
of a bigger effort, feel free to contribute to initiative as MDN (
http://developer.mozilla.
org
) or Dev.Opera (
http://dev.opera.com
). The W3C is also working on that topic and you
should heard more about this in a few weeks. Your help will always be welcome :)
5/5
by Holly Schinsky
liness
(
app
DON’T WORRY, BE APPLI
APPLE PUSH NOTIFICATIONS WITH
PHONEGAP
THIS IS PART 1 OF A NEW SERIES TO HELP EXPLAIN HOW TO SET UP AND USE APPLE PUSH NOTIFICA
-
TIONS (APNS) IN YOUR MOBILE APPLICATIONS.
APPLE PUSH NOTIFICATIONS
Push notifications are different than local notifications in that they are coming from a 3rd party server
to inform the user of something, versus a local notification which is scheduled by the application to run
on the device itself without any server interaction. For instance you may receive a push notification from
Facebook notifying you that someone has added you as a friend, or if you are a Words With Friends player
you may receive a push notification indicating it’s your turn. An example of a local notification would be
an alert popping up at a certain time or interval as a reminder from a to do application where you set a
date/time to a task and the alert pops up to remind you at that specified time. To the end user they may
appear the same in that they both pop alerts, can have sounds associated etc, but they are very different
from a development perspective.
There are Cordova/PhoneGap plugins to do both local and push notifications for iOS, but this series will
focus on push notifications. If you’re wondering about Android, there is a concept of push notifications
but the setup and process is a bit different and will be covered in a later post.
The process to get started with setting up APNs can be a bit intimidating
initially but it’s worth taking the time to do so as the use cases are endless.
This series is intended to help you understand the whole process including
setup and what is occurring on both the application and server-side with
sample code to get you started quickly..
APN WORKFLOW OVERVIEW
EXPLANATION OF WORKFLOW
Upon launch, your application communicates with the Apple Push Notification Service to authorize it to
receive push notifications.
Apple responds with a unique token that must be used in all future communications to receive push no
-
tifications.
Your application sends that token to a 3rd party server (your own or some other provider like Urban Air
-
ship for instance), that will store it for later events when the application needs to be notified.
When an event occurs where your application needs to receive a notification, the server script reads in
the unique device token and sends a message with a pre-defined structure to the Apple Push Notifica
-
tion Services which then securely sends to your device. The structure may include a message, sound and
badge number to display on the application launch icon or any combination of the three.
HIGH LEVEL HOW-TO (DETAILS TO FOLLOW):
1. iOS Provisioning Portal
Create a new App ID with push notifications enabled and an SSL Certificate associated
Create a new provisioning file for the above App ID and download it
Drag new provisioning file into XCode (or via XCode Organizer)
Associate new provisioning file with your Project in the Code Signing Options
2. Cordova/PhoneGap Plugin Setup
Download Cordova Plugin for PushNotifications
2/12
Add PushNotification plugin key and value to Cordova.plist
Drag PushNotification folder to XCode Plugins Folder (create groups for any added folders) – only the
PushNotification.m and PushNotification.h are needed here for the native, see next step for the Push
-
Notification.js client side
In Finder, copy the PushNotification.js file from your downloaded plugin into the existing www folder
Add a script tag to refer to the new PushNotification.js
Add methods to the AppDelegate.m (under Classes) to handle push notification events and code for
handling launch of application from a push notification
3. Client Side Application Handling
Add code to register the user’s device
Add code to listen for notification events when app is active
Add code for badge management (clear on relaunch from notification etc)
Add code to check user’s notification status – which options do they have set for this application spe
-
cifically (they can control notification type, badge/alert/sound)
Add code to get pending notifications (ie: if app is opened from the push notification, we need to ac
-
cess that notification to get the data passed in to see if updates are needed etc)
Include resources in your project for custom sounds or launch images to be associated with your push
notification
4. Server Side Handling (Optional)
Specify the URL to the Apple Push Notification Service gateway (sandbox or production)
Ensure proper certificates available on server
Specify any custom sounds
Special any launch images
Save registered device id’s in a database
SSL CERTIFICATES AND PROVISIONING
The first thing you need to do is set up certificates and provisioning to provide a secure connection for
communication between servers and your application. Don’t let this step scare you, it’s not that bad
once you do it . There’s a great article here that documents this process with screenshots and details
that you should use for this step. In the next paragraph I attempt to put words to exactly what it is
you’re doing and why for those that want to understand better, but feel free to skip that paragraph if
you just want to go through the setup
using the article
.
Certificates and Provisioning Explanation
Basically your application needs to be enabled for push notifications through the Apple iOS Provisioning Por
-
tal via an App ID (com.mysite.myapp) and signed with a provisioning profile that includes this push enabled
application identifier. The App ID also needs to be associated with an SSL certificate for communicating se
-
curely with Apple’s Push Notification Server. When you configure the App ID through the portal, a wizard will
prompt you to create an SSL certificate that will be associated with your App ID and used for that purpose.
Having the association with the App ID will will ensure the notifications sent from your server to Apple’s APN
Server will then be sent to *just* the application with that matching id. Once the certificate process is com
-
plete you will need to download a new provisioning file for this new App ID containing the enabled push
notifications. You then drag it into XCode and make sure it is the provisioning profile that is selected for your
3/12
application in the Code Signing screen (under Build Settings for your project).
SETTING UP YOUR APPLICATION
Now that you’re ready to start coding your HTML/JavaScript/PhoneGap application, go through the
following steps to set it up:
1. Get the latest PhoneGap Push Notifications plugin from GitHub.
2. Drag and drop the PushNotification folder to the Plugins folder in XCode and select the “Create
groups for any added folders” as the copy option as shown in the screenshot.
3. Go out of
XCode and into Finder
and copy the
PushNotification.js
file into your www folder (or in
a subfolder called plugins underneath the www folder to keep it cleaner). It will automatically show up
in XCode for you. You cannot drag a file into XCode into this folder because of the way that it’s set up
as a folder reference (icon is blue). See the
sample project for further reference
.
4. Add a script tag to refer to the PushNotification.js file in your HTML file such as:
//INSERT THIS LINE OF CODE
<script
src=”js/PushNot
if
ication.js”>
</script>
5. Add the plugin key and value to your
Cordova.plist
(found under your project root Resources fold
-
er)
4/12
The
Cordova PushNotification plugin
gives you a nice JavaScript API you can use from your HTML/JS files
to interact with the underlying native code for handling the registration and receiving of push notifica
-
tions. Some of the functions provided are listed here:
- registerDevice()
- setApplicationIconBadgeNumber()
- getRemoteNotificationStatus()
- getPendingNotifications()
To use it though, you first need to add some things to the native application code to bridge to the
specific push notification code. The
AppDelegate class
for an application (located under your project
Classes folder) implements the handlers for application-wide events, such as application launch, termi
-
nation and more. There are also events available for handling notifications. A list of them can be found
here in the Handling Notifications reference. These methods are not implemented by default though,
so in order to support them we need to add the code handlers and have them delegate to our included
PushNotification.m class in our plugin code. The code to add is shown in the README for the plugin but
I’ll paste it here as well for further reference. You’re basically handling three events with it:
- didReceiveRemoteNotification
- didRegisterForRemoteNotificationsWithDeviceToken
- didFailToRegisterForRemoteNotificationsWithError
Add the following code block to your
AppDelegate.m
class before the
@end
to handle the notification
events:
/* START BLOCK */
#pragma PushNot
if
ication delegation

- (void)application:(UIApplication*)app didRegisterForRemoteNot
if
icationsWithDevice
Token:(NSData*)deviceToken
{
PushNot
if
ication* pushHandler = [self.viewController getCommandInstance:@”PushN
ot
if
ication”];
[pushHandler didRegisterForRemoteNot
if
icationsWithDeviceToken:deviceToken];
}

- (void)application:(UIApplication*)app didFailToRegisterForRemoteNot
if
icationsWith
Error:(NSError*)error
{
PushNot
if
ication* pushHandler = [self.viewController getCommandInstance:@”PushN
ot
if
ication”];
[pushHandler didFailToRegisterForRemoteNot
if
icationsWithError:error];
}

- (void)application:(UIApplication*)application didReceiveRemoteNot
if
ication:(NSDic
tionary*)userInfo
{
PushNot
if
ication* pushHandler = [self.viewController getCommandInstance:@”PushN
ot
if
ication”];
NSMutableDictionary* mutableUserInfo = [userInfo mutableCopy];


// Get application state for iOS4.x+ devices, otherwise assume active
UIApplicationState appState = UIApplicationStateActive;

if
([application respondsToSelector:@selector(applicationState)]) {
appState = application.applicationState;
5/12
}

[mutableUserInfo setValue:@
”0”
forKey:@”applicationLaunchNot
if
ication”];

if
(appState == UIApplicationStateActive) {
[mutableUserInfo setValue:@
”1”
forKey:@”applicationStateActive”];
[pushHandler didReceiveRemoteNot
if
ication:mutableUserInfo];
}
else
{
[mutableUserInfo setValue:@
”0”
forKey:@”applicationStateActive”];
[mutableUserInfo setValue:[NSNumber numberWithDouble: [[NSDate date] ti
meIntervalSince1970]] forKey:@”timestamp”];
[pushHandler.pendingNot
if
ications addObject:mutableUserInfo];
}
}
/* STOP BLOCK */
The above code essentially creates a reference to our PushNotification class, sets or reads some values
(not going into detail here to keep this less complicated), and calls different methods with parameters
depending on the event that occurred.
The last thing you need to do is add a code fragment into the didFinishLaunchingWithOptions method
in that same AppDelegate.m class to handle opening the application from a notification (and adding the
received object to the pendingNotifications for later retrieval). Add this block right before the end return
YES:
/* Handler when launching application from push not
if
ication */

// PushNotification - Handle launch from a push notification
NSDictionary* userInfo = [launchOptions objectForKey:UIApplicationLaunchO
ptionsRemoteNot
if
icationKey];

if
(userInfo) {
PushNot
if
ication *pushHandler = [self.viewController getCommandInstan
ce:@”PushNot
if
ication”];
NSMutableDictionary* mutableUserInfo = [userInfo mutableCopy];
[mutableUserInfo setValue:@
”1”
forKey:@”applicationLaunchNot
if
icati
on”];
[mutableUserInfo setValue:@
”0”
forKey:@”applicationStateActive”];
[pushHandler.pendingNot
if
ications addObject:mutableUserInfo];
}
/* end code block */
PUSHNOTIFICATION PLUGIN – JAVASCRIPT APIS
Now that you have the project setup complete including the native Objective-C handlers above, you
can actually start coding with the Cordova PushNotification JavaScript interfaces. Below is further detail
about some of them and examples of interacting with then in your code. Note: there are others that are
available but not covered specifically yet in this post.
REGISTER DEVICE
The
PhoneGap PushNotification plugin
offers a
registerDevice()
API to register your application
with Apple’s Push Notification Service to receive push notifications. In the function you specify exactly
which types of notifications are enabled (alerts/badges/sounds). The result is a unique device token that
can then be used by the server-side to send the notification to that device.
Apple recommends you register your application for push notifications on the device every time it’s run
6/12
since tokens can change. The documentation says: ‘By requesting the device token and passing it to the
provider every time your application launches, you help to ensure that the provider has the current token
for the device. If a user restores a backup to a device other than the one that the backup was created
for (for example, the user migrates data to a new device), he or she must launch the application at least
once for it to receive notifications again. If the user restores backup data to a new device or reinstalls the
operating system, the device token changes. Moreover, never cache a device token and give that to your
provider; always get the token from the system whenever you need it.’
An example of using the registerDevice() function is included in the sample project and is also shown be
-
low:
var
pushNot
if
ication = window.plugins.pushNot
if
ication;
pushNot
if
ication.registerDevice({alert:true, badge:true, sound:true},

function
(status) {
app.myLog.value+=JSON.string
if
y([‘registerDevice status: ‘,
status])+”\n”;
app.storeToken(status.deviceToken);
});
Once the above code is in place and your application is run, you will receive an alert like the following
prompting if it’s ok to receive push notifications (this results in a setting that can be modified in your de
-
vice settings as needed):
GET PENDING NOTIFICATIONS
Pending notifications are those notifications that are received while the application was not active. When
the application is launched you will want to retrieve them so you can handle the data sent to you as
needed. The getPendingNotifications() function is available in the API for that purpose. Below is some
example code:
var
pushNot
if
ication = window.plugins.pushNot
if
ication;
pushNot
if
ication.getPendingNot
if
ications(
function
(not
if
ications) {
app.myLog.value+=JSON.string
if
y([
‘getPendingNot
if
ications’
,
not
if
ications])+”\n”;
console.log(JSON.string
if
y([
‘getPendingNot
if
ications’
, not
if
ications]));
});
GET NOTIFICATION STATUS
This method will return type and which notifications are enabled (alert, sound, badge).
var
pushNot
if
ication = window.plugins.pushNot
if
ication;
pushNot
if
ication.getRemoteNot
if
icationStatus(
function
(status) {
7/12
app.myLog.value+=JSON.string
if
y([‘Registration check - getRemoteNot
if
ica
tionStatus’, status])+”\n”;
});
SET BADGE NUMBER
You will likely need to set the badge number on the application icon as you process the notifications, for
instance if you open from a push notification just received, you may want to decrement or clear it. Setting
the badge number to 0 will remove or clear the badge as shown below.
var
pushNot
if
ication = window.plugins.pushNot
if
ication;
app.myLog.value+=”Clear badge... \n”;
pushNot
if
ication.setApplicationIconBadgeNumber(num);
ANATOMY OF AN APPLE PUSH NOTIFICATION
The maximum size for a notification payload is 256 bytes. If that limit is exceeded, it will be refused. Also
note the delivery of notifications is “best effort” and not guaranteed, according to the Apple documenta
-
tion, so you should not use it for sending critical or sensitive data, only to notify that new data is available.
The notification payload is a JSON dictionary object that needs to contain another dictionary identified
by the key aps. The aps dictionary then will contain one or more properties that would specify an alert
to display, a number badge to set on the application icon and/or a sound to play when the notification
occurs. It’s also possible to create a custom payload but that is beyond the scope of this post. The alert
object itself can contain just a string of text to display, OR a dictionary object with keys for a body, custom
action button text to display and a custom launch image that can be set. More specific details about the
payload can
be found here
.
Here’s an example of a simple payload in bytes:
A typical aps dictionary object will contain 3 properties; alert, badge and sound, such as shown in the fol
-
lowing output:
applicationLaunchNotification = 0;
applicationStateActive = 0;
aps = {
alert = {
“action-loc-key” = Play;
body = “Your turn!”;
“launch-image” = “mysplash.png”;
};
badge = 5;
sound = “notification-beep.wav”;
8/12
};
messageFrom = Holly;
timestamp = “1350416054.782263”;
Any custom sounds or launch images must be contained in the Resources folder in your project (under
XCode)your projects Resources folder in XCode. For example in my image below, I have a notification-
beep.wav and mysplash.png specified that I refer to in my push notification coming from the server.
SERVER-SIDE CODE HANDLING
LISTENING FOR DEVICE REGISTRATION TOKEN WITH NODE.JS
Below is example code you could use to get started with a server-side solution to handling device token
registration which I currently call from my application sample to show how and at which point you might
want to communicate with a 3rd party server to store device tokens after receiving the device token from
Apple. Currently it doesn’t do anything with the token other than show that it and the message were re
-
ceived, but the next step would be to store the users’s device token and any other information in a data
-
base for later use when a push notification needs to be sent (such as shown in the next example). I plan
to do a Part 2 series on integrating with MongoDB so check back soon!
var
http = require(
‘http’
);
var
apn = require(
‘apn’
);
var
qs = require(
‘querystring’
);

var
server = http.createServer(
function
(req, res) {

if
(req.method ===
“POST”
) {
9/12

var
fullBody=””;

req.on(
‘data’
,
function
(chunk)
{
fullBody += chunk;
console.log(“Full body “ + fullBody);
});

req.on(
‘end’
,
function
()
{

var
data = qs.parse(fullBody);
console.log(“Token “ +data.token);
console.log(“Message “ + data.message);

var
myDevice = new apn.Device(data.token);

// Now we need to store it! Add code to interface with a db
below...

res.writeHead(200, {“Content-Type”: “text/plain”});
res.end(“Thank you for registering\n”);
res.end();
});
}
}).listen(8888);
console.log(“Server running at http:/ /127.0.0.1:”+server.address().port);
Note: I’m simply running this script using Node.js on my localhost. When testing from your actual device
(since push notifications are not supported in the emulator), you can set up a Manual HTTP Proxy in your
device’s Wi-Fi settings to point to the IP Address of your computer. Go to your Wi-Fi network and scroll
to the bottom of the settings to set the Manual Proxy server and port. Here’s an example of mine
:
10/12
SENDING A NOTIFICATION WITH ARGON (NODE.JS API)
Below is an example of some simple code to show how you could use the argon open source Node.js API
to send a push notification to a users device. I simply hard-coded my device tokens in for quick testing,
but ultimately you would be retrieving them from a database (after being stored above) to use for send
-
ing the push notifications.
var
http = require(
‘http’
);
var
apn = require(
‘apn’
);
var
url = require(
‘url’
);

var
myPhone = “d2d8d2a652148a5cea89d827d23eee0d34447722a2e7defe
72fe19d733697fb0”;
var
myiPad = “51798aaef34f439bbb57d6e668c5c5a780049dae840a0a3626453cd4922b
c7ac”;

var
myDevice = new apn.Device(myPhone);

var
note = new apn.Not
if
ication();
note.badge = 1;
note.sound = “not
if
ication-beep.wav”;
note.alert = {
“body”
: “Your turn!”, “action-loc-key” :
“Play”
, “launch-im
age” : “mysplash.png”};
note.payload = {‘messageFrom’: ‘Holly’};

note.device = myDevice;

var
callback =
function
(errorNum, not
if
ication){
console.log(‘Error is: %s’, errorNum);
console.log(“Note “ + not
if
ication);
}
var
options = {
gateway: ‘gateway.sandbox.push.apple.com’,
// this URL is different for
Apple’s Production Servers and changes when you go to production
errorCallback: callback,
cert: ‘PushNot
if
icationSampleCert.pem’,
key: ‘PushNot
if
icationSampleKey.pem’,
passphrase:
‘myPassword’
,
port: 2195,
enhanced: true,
cacheLength: 100
}
var
apnsConnection = new apn.Connection(options);
apnsConnection.sendNot
if
ication(note);
The above code will produce a notification that looks like the following
on my device if you have your device
Settings->Notifications->MyAppName set to Alerts:
11/12
If you’re device settings for Alert Style on the application is set to Banners, it will look like this:
Important Note:
You need to change the .pem files to your cert and private key created in the setup (the
ones you ultimately combined into a single .pem with instructions from here. Remember you first con
-
verted the .cer to a .pem, and then your .p12 to a .pem, those are the two files needed here – see this
readme for more details on argon parameters). In my example, my .pem files are in the same folder as my
Node.js code. You can omit the password property if you did not keep a password on them.
There’s also a PHP Push Notifications API called APNS-PHP if you prefer to use PHP as your language of
choice…
SAMPLE PROJECT
I’ve included a link to
a sample project on GitHub
that I created for a reference application since it includes
everything discussed above already in place. You can’t actually use this project out of the box because
you have to have your own uniqe App ID and Provisioning files set on your project for it so you are bet
-
ter off starting your own project from scratch and using mine for reference only. I created this project to
eventually be cross-platform using the cordova-client tool, but currently only iOS is setup so refer to the
PGPushNotificationSample/platforms/ios path for the iOS specific code. You’ll find all of the JavaScript
functions in the PGPushNotificationSample/platforms/ios/www/js/index.js file. I chose straight JavaScript
in favor of simplicity. It also does an XMLHttpRequest to my simple server code (example shown above)
and sends the device token received from the registration.
app
(
by Nicholas Zakas
DON’T WORRY, BE APPLI
liness
DOES JAVASCRIPT NEED CLASSES?
IN THIS ARTICLE, NICHOLAS CLEARS UP CONFUSION AROUND THE TERMINOLOGY OF CLASSES (OR
LACK THEREOF) WHEN CODING IN JAVASCRIPT.
CLASSLESS JAVASCRIPT
Like it or not,
ECMAScript 6
is going to have classes[1]. The concept of classes in JavaScript has always
been polarizing. There are some who love the classless nature of JavaScript specifically because it is dif
-
ferent than other languages. On the other hand, there are those who hate the classless nature of JavaS
-
cript because it’s different than other languages. One of the biggest mental hurdles people need to jump
when moving from C++ or Java to JavaScript is the lack of classes, and I’ve had people explain to me that
this was one of the reasons they either didn’t like JavaScript or decided not to continue learning.
JavaScript hasn’t had a formal definition of classes since it was first created and that has caused confusion
right from the start. There are no shortage of JavaScript books and articles talking about classes as if they
were real things in JavaScript. What they refer to as classes are really just custom constructors used to
define custom reference types. Reference types are the closest thing to classes in JavaScript. The general
format is pretty familiar to most developers, but here’s an example:
function
MyCustomType(value) {
this.property = value;
}
MyCustomType.prototype.method =
function
() {

return
this.property;
};
In many places, this code is described as declaring a class named
MyCustomType
. In fact, all it does is
declare a function named
MyCustomType
that is intended to be used with
new
to create an instance of
the reference type
MyCustomType
. But there is nothing special about this function, nothing that says it’s
any different from any other function that is not being used to create a new object. It’s the usage of the
function that makes it a constructor.
The code doesn’t even look like it’s defining a class. In fact, there is very little obvious relationship be
-
tween the constructor definition and the one method on the prototype. These look like two completely
separate pieces of code to new JavaScript developers. Yes, there’s an obvious relationship between the
two pieces of code, but it doesn’t look anything like defining a class in another language.
Even more confusing is when people start to talk about inheritance. Immediately they start throwing
around terms such as subclassing and superclasses, concepts that only make sense when you actually
have classes to work with. Of course, the syntax for inheritance is equally confusing and verbose:
function
Animal(name) {
this.name = name;
}
Animal.prototype.sayName =
function
() {
console.log(this.name);
};
function
Dog(name) {
Animal.call(this, name);
}
Dog.prototype = new Animal(null);
Dog.prototype.bark =
function
() {
console.log(“Woof!”);
};
The two-step inheritance process of using a constructor and overriding a prototype is very confusing.
In the first edition of Professional JavaScript for Web Developers, I used the term “class” exclusively. The
feedback I received indicated that people found this confusing and so I changed all references to “class”
in the second edition to “type”. I’ve used that terminology ever since and it helps to eliminate a lot of
the confusion.
However, there is still a glaring problem. The syntax for defining custom types is confusing and verbose.
Inheritance between two types is a multistep process. There is no easy way to call a method on a super
-
type. Bottom line: it’s a pain to create and manage custom types. If you don’t believe that this is a prob
-
lem, just look at the number of JavaScript libraries that have introduced their own way of defining custom
types, inheritance, or both:

YUI
– has
Y.extend()
to perform inheritance. Also adds a
superclass
property when using this
method.[2]

Prototype
– has
Class.create()
and
Object.extend()
for working with objects and “classes”.[3]

Dojo
– has
dojo.declare()
and
dojo.extend()
.[4]

MooTools
– has a custom type called
Class
for defining and extending classes.[5]
It’s pretty obvious that there’s a problem when so many JavaScript libraries are defining solutions. Defin
-
ing custom types is messy and not at all intuitive. JavaScript developers need something better than the
current syntax.
ECMAScript 6 classes are actually nothing more than syntactic sugar on top of the patterns you are al
-
ready familiar with. Consider this example:
2/4
class MyCustomType {
constructor(value) {
this.property = value;
}
method() {

return
this.property;
}
}
This ECMAScript 6 class definition actually desugars to the previous example in this post. An object cre
-
ated using this class definition works exactly the same as an object created using the constructor defini
-
tion from earlier. The only difference is a more compact syntax. How about inheritance:
class Animal {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
class Dog extends Animal {
constructor(name) {
super(name);
}
bark() {
console.log(“Woof!”);
}
}
This example desugars to the previous inheritance example. The class definitions are compact and the
clunky multistep inheritance pattern has been replaced with a simple
extends
keyword. You also get the
benefit of
super()
inside of class definitions so you don’t need to reference the supertype in more than
one spot.
All of the current ECMAScript 6 class proposal is simply new syntax on top of the patterns you already
know in JavaScript. Inheritance works the same as always (prototype chaining plus calling a supertype
constructor), methods are added to prototypes, and properties are declared in the constructor. The only
real difference is less typing for you (no pun intended). Class definitions are just type definitions with a
different syntax.
So while some are having a fit because ECMAScript 6 is introducing classes, keep in mind that this con
-
cept of classes is abstract. It doesn’t fundamentally change how JavaScript works; it’s not introducing a
new thing. Classes are simply syntactic sugar on top of the custom types you’ve been working with for a
while. This solves a problem that JavaScript has had for a long time, which is the verbosity and confusion
of defining your own types. I personally would have liked to use the keyword
type
instead of
class
, but
at the end of the day, this is just a matter of semantics.
So does JavaScript need classes? No, but JavaScript definitely needs a cleaner way of defining custom
types. It just so happens the way to do that has a name of “class” in ECMAScript 6. And if that helps de
-
velopers from other languages make an easier transition into JavaScript, then that’s a good thing.
3/4
ABOUT THIS ARTICLE
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 li
-
brary. He is the author of Maintainable JavaScript
(O’ Reilly, 2012), Professional JavaScript for Devel
-
opers (Wrox, 2012), High Performance JavaScript
(O’Reilly, 2010), and Professional Ajax (Wrox, 2007).

http://www.nczonline.net/
@slicknet
Maintainable JavaScript
http://www.amazon.com
JavaScript for Developers
http://www.amazon.com/
High Performance JavaScript (Build Faster Web
Application Interfaces)
http://www.amazon.com
ONLINE RESOURCES
REFERENCES
1.
Maximally minimal classes
(ECMA)
2.
YUI extend()
(YUILibrary)
3.
Prototype Classes and Inheritance
(Prototype)
4.
Creating and Enhancing Dojo Classes
(SitePen)
5.
MooTools Class
(MooTools)
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.
app
DON’T WORRY, BE APPLI
by Piotr Walczyszyn
(
liness
NATIVE SCROLLING IN JQUERY MOBILE/
PHONEGAP APPLICATIONS
PIOTR DISCUSSES SOME TECHNIQUES FOR HANDLING SCROLLING WHEN DEVELOPING MOBILE APPS
USING PHONEGAP AND JQUERY MOBILE FOR IOS AND ANDROID.
In one of my
previous
blog posts, I covered how to fix flickers and jumps during page transitions when
using
jQuery Mobile
with
PhoneGap
. The good news is that flickers were eliminated with latest release
of PhoneGap 2.1 and its departure from using IFrame for JavaScript to Native bridge. Unfortunately, the
issue of 1px jumps is still there, but that is by design in jQuery Mobile. So, this means my solution with
additional div element hosting application content is still valid.
Unfortunately, my approach has a drawback of losing jQuery Mobile out-of-the-box content scrolling. A
workaround I found for this is to use absolute positioning and native css declarable scrolling. By native
css declarable scrolling, I understand using the
overflow
property with the scroll value and
-webkit-
overflow-scrolling
set to
touch
. You have to be careful when using these, as it may not work on all
devices. I know iOS supports it from version 5 and above. In case of Android only
overflow: scroll
is
actually working, which means you will not have a rubber band effect, but your content will actually scroll
– which in case of Android is often good enough. For devices that don’t support it, you may want to use
the
Overthrow
library which nicely polyfills it, or any other libs like:
iScroll
,
Scrollability
or
ScrollView
.
The snippet below demonstrates it in detail, you can also run it from
here
. As you can see, I had to ab
-
solutely position the
header
and
content
elements. In addition, I added the
.scrollable
css class
that enables native scrolling of its content. One thing to note here is that I
had to enforce hardware acceleration of scrolled elements with
-webkit-
transform: translateZ(0px);
property. This only works on iOS so
make sure you don’t use this declaration on Android. BTW, Apple has fixed
it in iOS 6 and enforcing hardware acceleration will not be necessary in the
future.
<<< YOU CAN SCROLL DOWN THE CONTENT OF THIS FRAME >>>
Try
me!
2/2
PAUL
D.
HUNT
DESIGNER

OF
SOURCE
CODE
PRO
“In designing Source
Code Pro, I tried to
resolve many of the
things that bothered
me personally in other
designs.”
EXCLUSIVE INTERVIEW
Copyright - Rey Rey’s Photography
1/3
HI PAUL, CAN YOU INTRODUCE YOURSELF TO OUR READERS? HOW DID YOU BECOME
A FONT DESIGNER?
I started into type design out of curiosity. I wanted to find out what it takes to make a font
and so I found some tutorials online and began with experimenting with drawing Cyrillic
characters for existing freeware fonts. In my online searches I came across the Typophile
web forums, which were quite active at the time, and was able to learn a lot by posing
questions directly to designers and developers working in typeface design.
As part of my self-guided type education, I taught myself how to do
OpenType programming
.
With this skill in hand, I was presented with the rare opportunity to work as an intern for
a type foundry. My stint with P22 Type Foundry quickly morphed from an internship to a
full-time job and I remained there for three years. After that time, I felt that I had a good
base in the technical aspects of type production, but wanted to focus more on learning the
design aspects.
At that point, I felt that the best option for me to do this was to enroll in the Masters
course in typeface design at the University of Reading, UK. There I was able to work on
my digital letter drawing skills and learned to better understand how to create a cohesive
visual language for writing systems. After graduation, Adobe asked me to come work for
them and I have been here ever since continuing to build on my skills in both programming
and designing fonts.
YOU DESIGNED A FONT FOR CODERS. HOW DID YOU IDENTIFY WHAT DEVELOPERS
EXPECT?
In designing a monospaced typeface, I drew primarily from my own experience using such
fonts. As you can gather from my personal story, it was my ability to do some coding that
helped me to find my way into typeface design.
Much of my time spent in developing fonts is in editing text files, which are used by our
tools to compile font software. So I’m familiar with the shortcoming of many of the existing
monospaced fonts. In designing Source Code Pro, I tried to resolve many of the things that
bothered me personally in other designs. Also, I got very good feedback in working directly
with the Brackets team, for whom we created this font family.
Discover Source Code Pro:
0
1
234567
8
9
A
B
CDEFGHIJK
L
MN
O
PQRSTUVWXYZ
abcdefghijk
l
mnopqrstuvwxyz
2/3
WHAT MAKES SOURCE CODE PRO A UNIQUE FONT?
In terms of design, I’m not sure how unique this type family is. I tried to keep the details as
simple as possible as I find a common problem with many monospaced fonts is that they
feature too many distracting elements.
I also tried to make the type design more readable by giving the letterforms more pleasing
proportions. That said, there are other fonts that do these things. However, I feel that as
a open source project this type family is truly unique as we have tried to make the font
sources as accessible as possible so that other parties can customize this project as needed.
WHAT ARE THE BENEFITS OF AN OPEN-SOURCE FONT? DESIGNERS CAN FORK THE
PROJECT ? :)
In terms of benefits to Adobe, I feel that our open source font projects have generated
quite a bit of good will in the design and developer communities that we are trying to
connect with. Also making Source Code and its sister family Source Sans Pro open source
provides better type options for our own open source projects that need fonts for UI.
These projects, due to their open nature, can also be used as
learning tools for people
wanting to learn how to develop fonts
. Lastly, because these projects are open, other
parties can help contribute to their success. We recently added more functionality to the
Source Sans family with the help and support of a third party, Logos Bible Software. The
work that they commissioned can benefit us as well as all users of these fonts.
ARE YOU CURRENTLY WORKING ON A NEW FONT?
I am continuing to extend the functionality of the Source family of fonts, and I see that
there is possibility for this to continue for the next several years. Currently I am drawing
Greek and Cyrillic characters for the Source Sans family and I hope that these additions will
eventually make their way into the Source Code fonts as well. In addition to this work, I just
finished a typeface family for Gurmukhi script.
And that’s all the design work I’m doing at the moment, but there is always more font
development work for me whether I’m drawing or not. This means I’ll be looking at a lot of
monospaced text... :^D
Get Source Code Pro:
https://github.com/adobe/Source-Code-Pro
3/3
(
by Karl Sequin
DON’T WORRY, BE APPLI
liness
app
NODE.JS, REQUIRE AND EXPORTS
IN THIS ARTICLE, KARL SHARES WHAT HE HAS LEARNED FROM USING NODE.JS IN CONJUNCTION WITH
REQUIRE TO EXPOSE CODE ELEMENTS TO OTHER MODULES.
Back when I first started playing with node.js, there was one
thing that always made me uncomfortable. Embarrassingly, I’m
talking about
module.exports
. I say
embarrassingly
because
it’s such a fundamental part of node.js and it’s quite simple. In
fact, looking back, I have no idea what my hang up was...I just
remember being fuzzy on it. Assuming I’m not the only one who’s had to take a second, and third, look
at it before it finally started sinking in, I thought I could do a little write up.
In Node, things are only visible to other things in the same file. By
things
, I mean variables, functions,
classes and class members. So, given a file
misc.js
with the following contents:
var
x = 5;
var
addX =
function
(value) {

return
value + x;
};
Another file cannot access the
x
variable or
addX
function. This has nothing to do with the use of the
var

keyword. Rather, the fundamental Node building block is called a
module
which maps directly to a file.
So we could say that the above file corresponds to a module named
file1
and everything within that
module (or any module) is private.
Now, before we look at how to expose things out of a module, let’s look at loading a module. This is
where
require
comes in.
require
is used to load a module, which is why its return value is typically as
-
signed to a variable:
var
misc = require(‘./misc’);
Of course, as long as our module doesn’t expose anything, the above isn’t very useful. To expose things
we use
module.exports
and export everything we want:
var
x = 5;
var
addX =
function
(value) {

return
value + x;
};
module.exports.x = x;
module.exports.addX = addX;
Now we can use our loaded module:
var
misc = require(‘./misc’);
console.log(“Adding %d to 10 gives us %d”, misc.x, misc.addX(10));
There’s another way to expose things in a module:
var
User =
function
(name, email) {
this.name = name;
this.email = email;
};
module.exports = User;
The difference is subtle but important. See it? We are exporting user directly, without any indirection. The
difference between:
module.exports.User = User;
//vs
module.exports = User;
is all about how it’s used:
var
user = require(‘./user’);
var
u = new user.User();
//vs
var
u = new user();
It’s pretty much a matter of whether your module is a container of exported values or not. You can actu
-
ally mix the two within the same module, but I think that leads to a pretty ugly API.
Finally, the last thing to consider is what happens when you directly export a function:
var
powerLevel =
function
(level) {

return
level > 9000 ? “it’s over 9000!!!” : level;
};
module.exports = powerLevel;
2/3
ABOUT THIS ARTICLE
My name is Karl Sequin, I’m a software developer
and amateur writer. I contribute to various open
source projects, run a few side projects and enjoy
learning new technologies.

http://openmymind.net/
@karlsequin
Node.js
http://nodejs.org/
RequireJS
http://requirejs.org/
Karl’s blog
http://openmymind.net/
ONLINE RESOURCES
When you require the above file, the returned value is the actual function. This means that you can do:
require(‘./powerlevel’)(9050);
Which is really just a condensed version of:
var
powerLevel = require(‘./powerlevel’)
powerLevel(9050);
Hope that helps!
(
DON’T WORRY, BE APPLI
liness
app
by Karl Sequin
NODE.JS, MODULE.EXPORTS AND
ORGANIZING EXPRESS.JS ROUTES
A WHILE AGO I WROTE A POST EXPLAINING
HOW REQUIRE AND MODULE.EXPORTS WORK
. TODAY I
WANTED TO SHOW A PRACTICAL EXAMPLE OF HOW WE CAN USE THAT KNOWLEDGE TO ORGANIZE
ROUTES IN AN EXPRESS.JS PROJECT.
To recap the original post,
module.exports
is how we make
something within our file publicly accessible to anything outside
our file. We can export anything: a class, a hash, a function or
a variable. When you
require
something you get whatever it
exported. That means that the return value from
require
can
be a class, a hash, a function or a variable. The end result is that how the value returned from
require

is used can vary quite a bit:
# the user file exported a class
User = require(‘./models/user’)
leto = new User()
# the initialize file exported a
function
initliaze = require(‘./store/inialize’)
initialize(config)
# the models file exported as hash (which has a User
key which was an object)
Models = require(‘./models’)
user = new Models.User()
With that in mind, I happen to be building a website that’ll have two distinct sections: an API and a user-
facing portal. I’d like to organize my routes/controllers as cleanly as possible. The structure that I’d like is:
/routes
/routes/api/
/routes/api/stats.coffee
/routes/api/scores.coffee
/routes/portal/
/routes/portal/users.coffee
/routes/portal/stats.coffee
This is very Rails-esque with controller namespaces and resources. Ideally, I’d like controllers under API
(stats and scores) to have access to common API-based methods. How can we cleanly achieve this?
Before we can dive any further we need to understand how express loads routes. You basically attach the
route to the express object. The simplest example might look something like:
express = require(
‘express’
)
app = express.createServer()
app.configure ->
app.use(app.router)
app.get ‘/’, (req, res) ->
res.send(‘hello world’)
On line 4 we tell express to enable its routing, and then use the
get
and
post
methods (to name a few)
to define our routes.
Taking a baby step, if we wanted to extract our route into its own file, we could do:
# routes.coffee
module.exports = (app) ->
app.get ‘/’, (req, res) ->
res.send(‘hello world’)
# and use it like so:
express = require(
‘express’
)
app = express.createServer()
app.configure ->
app.use(app.router)
require(‘./routes’)(app)
The syntax might be strange, but there’s nothing new here. First, our
exports
isn’t doing anything other
than exporting a function that takes a single parameter. Secondly, our require is loading that function and
executing it. We could have rewritten the relevant parts more verbosely as:
# routes.coffee
routes: (app) ->
....
module.exports = routes
# and use it like so:
routes = require(‘./routes’)
routes(app)
2/5
So how do we take this to the next level? Well, we don’t want to have to import a bunch of different
routes at the base level. We want to use
require(‘./routes’)(app)
and let that load all the neces
-
sary routes. So, the first thing we’ll do is put an
index
file in a routes folder:
# routes/index.coffee
module.exports = (app) ->
require(‘./api’)(app)
require(‘./portal’)(app)
When you tell node.js to require a folder, it automatically loads its index file. With the above, our initial
route loading remains untouched:
require(‘./routes’)(app)
. Now, this loading code doesn’t just
include
routes/index.coffee
it actually executes it (it’s calling the function and passing in the app as
an argument). All our routes function does is load and execute more functions.
For both our API and portal, we can do the same thing we did for routes:
# routes/api/index.coffee
module.exports = (app) ->
require(‘./stats’)
require(‘./scores’)
Stats and scores can contain actual routes:
# routes/api/scores.coffee
module.exports = (app) ->
app.post ‘/api/scores’, (req, res) ->
# save as score
app.get ‘/api/scores’, (req, res) ->
# get scores
# routes/api/stats.coffee
module.exports = (app) ->
app.post ‘/api/stats’, (req, res) ->
# save a stat
This is a good solution to help us organize our code, but what about sharing behavior? For example,
many API functions will want to make sure requests are authenticate (say, using an SHA1 hash of the pa
-
rameters and signature).
Our first attempt will be to add some utility methods to the
api/index.coffee
file:
# routes/api/index.coffee
routes = (app) ->
require(‘./stats’)
require(‘./scores’)
signed = (req, res, next) ->

if
is_signed(req)
next()

else
res.send(‘invalid signature’, 400)
is_signed = (req) ->
#how to sign a request isn’t the point of this port
3/5
module.exports =
routes: routes
signed: signed
Since we are now exporting a hash rather than a function, our
routes/index.coffee
file also needs
to change:
# OLD routes/index.coffee
module.exports = (app) ->
require(‘./api’)(app)
require(‘./portal’)(app)
# NEW routes/index.coffee
module.exports = (app) ->
require(‘./api’).routes(app)
require(‘./portal’).routes(app) #assuming we do the same to portal
Now, we can use our signed method from our scores route:
# routes/api/scores.coffee
api = require(‘./index’)
module.exports = (app) ->
app.post ‘/api/scores’, api.signed, (req, res) ->
# save as score
For those who don’t know, when an express route is given 3 parameters, the 2nd one is treated as some
-
thing of a before-filter (you can pass in an array of them and they’ll be processed in order).
This solution is pretty good, but we can take it a step further and create some inheritance. The main ben
-
efit is not having to specify
api
. all over the place. So, we change our
api/index.coffee
one last time:
# routes/api/index.coffee
routes = (app) ->
require(‘./stats’)
require(‘./scores’)
class Api
@signed = (req, res, next) =>

if
@is_signed(req)
next()

else
res.send(‘invalid signature’, 400)
@is_signed = (req) ->
#how to sign a request isn’t the point of this port
module.exports =
routes: routes
Api: Api
4/5
ABOUT THIS ARTICLE
My name is Karl Sequin, I’m a software developer
and amateur writer. I contribute to various open
source projects, run a few side projects and enjoy
learning new technologies.

http://openmymind.net/
@karlsequin
Node.js
http://nodejs.org/
RequireJS
http://requirejs.org/
Karl’s blog
http://openmymind.net/
ONLINE RESOURCES
Since the routes are still exposed the same way, we don’t have to change the main
routes/index.
coffee
file. However, we can change our scores files like so:
class Scores extends require(‘./index’).Api
@routes: (app) =>
app.post ‘/api/scores’, @signed, (req, res) ->
# save as score
module.exports = Scores.routes
And that, is that. There’s a lot going on in all of this, but the key takeaway is that you can export anything
and that flexibility can lead to some fairly well organized code. You can also leverage the fact that the
index
file is automatically loaded when its folder is required to keep things nice and clean.
I know this jumped all over the place, but hopefully you’ll find it helpful!
by Andrew Trice
app
(
liness
DON’T WORRY, BE APPLI
PHONEGAP, APPLE REJECTIONS & UI/UX
GUIDELINES
READ HOW TO GET YOUR PHONEGAP APPLICATION APPROVED BY APPLE.
REJECTION
I’ve recently encountered some grumblings from the development community that Apple has rejected
their PhoneGap apps for not being “native enough”. By itself, that doesn’t surprise me too much – Ap
-
ple has very strict rules/guidelines on what they will and will not accept into the App Store. What did
surprise me is that people were blaming PhoneGap as the reason. This accusation is not accurate, and in
this post I’ll attempt to clear things up.
APPLE & HTML
First, let’s talk about Apple & HTML. Apple does not reject applications because their user interface is
built using HTML. In fact, many of Apple’s own apps or advertising platforms for iOS are entirely built
with HTML/CSS/JS. For instance, the Apple Store and iAd advertising platform, among others, use HTML
as the primary content for the user interface. Outside of Apple there are
many successful apps that have user interfaces built with HTML, including
LinkedIn, Wikipedia, the BBC Olympics, and
many, many others
.
Note: Not all these apps mentioned use PhoneGap, but they do use HTML
for the UI.
Apple will reject applications that do not have a user experience that feels like an “app”, does not feel
“at home” in the iOS ecosystem, or offers no advantage over a mobile web experience. This applies to all
apps, not just apps developed using HTML for the UI. I don’t work for Apple, so I don’t know what their
exact approval rules are (
beyond these
and
these
) but I can guarantee you that it largely comes down to
how the user interacts with the app and how it “feels” on the device.
The
iOS User Interface Guidelines
from Apple have a very large amount of information about what is and
what is not acceptable for Apple’s ecosystem. In these UI Guidelines,
Apple specifically addresses “web-
based designs”
:
Reconsider Web-Based Designs
If you’re coming from the web, you need to make sure that you give people an iOS app experience, not
a web experience.
Remember, people can visit your website on their iOS-based devices using Safari on
iOS.
Here are some strategies that can help web developers create an iOS app:
Focus your app.
Websites often greet visitors with a large number of tasks and options from which they
can choose, but this type of experience does not translate well to iOS apps. iOS users expect an app to
do what it advertises, and they want to see useful content immediately.
Make sure your app lets people do something.
People might enjoy viewing marketing content in the
websites they visit, but they expect to accomplish something in an app.
Design for touch.
Don’t try to replicate web UI design paradigms in your iOS app. Instead, get familiar
with the UI elements and patterns of iOS and use them to showcase your content. Web elements you’ll
need to re-examine include menus, interactions initiated by hovering, and links.
Let people scroll.
Most websites take care to display the most important information in the top half of
the page where it is seen first (“above the fold”), because people sometimes leave a page when they
don’t find what they’re looking for near the top. But on iOS-based devices, scrolling is an easy, expected
part of the experience. If you reduce font size or squeeze controls to fit your content into the space of
a single device screen, you’re likely to end up with unreadable content and an unusable layout.
Relocate the homepage icon.
Websites often display an icon that links to the homepage at the top of
every webpage. iOS apps don’t include homepages, so this behavior is unnecessary. In addition, iOS
apps allow people to tap the status bar to quickly scroll back to the top of a long list. If you center a tap
-
pable home icon at the top of the screen, it’s very difficult for users to tap the status bar instead.
In addition to the iOS User Interface Guidelines, Apple’s
App Store Review Guidelines
have additional
tips for getting your apps approved. Many relate to HTML-based experiences, including:
2.7: Apps that download code in any way or form will be rejected
2.12: Apps that are not very useful, unique, are simply web sites bundled as Apps, or do not provide any
lasting entertainment value may be rejected
10.3: Apps that do not use system provided items, such as buttons and icons, correctly and as described
in the
Apple iOS Human Interface Guidelines
may be rejected
10.6: Apple and our customers place a high value on simple, refined, creative, well thought through in
-
terfaces. They take more work but are worth it. Apple sets a high bar. If your user interface is complex
or less than very good, it may be rejected
12.3: Apps that are simply web clippings, content aggregators, or a collection of links, may be rejected
As I mentioned earlier, I don’t know all of Apple’s rules, but I do know this:
- If your app is just a web site wrapped in PhoneGap, it will probably get rejected. There are excep
-
2/3
tions to this case, but don’t expect that wrapping a web site in a web view will get you into the App
Store.
- If your app requires the user to pinch/zoom/pan to view content (like a web site), it will probably get
rejected. Your apps need to feel like apps.
- If your app just looks like text on a page with hyperlinks, and has no native-like styles, it will probably
get rejected.
App store approval often seems like a blurry line, and is very much subjective to the apps that are being
evaluated.
PHONEGAP
Now, let’s examine what PhoneGap is exactly, and how it fits into this context… From the PhoneGap FAQ:
“PhoneGap is an open source solution for building cross-platform mobile apps with standards-based Web
technologies like HTML, JavaScript, CSS.” For a much more detailed description of PhoneGap, see my
previous post
“PhoneGap Explained Visually”
. PhoneGap acts as a container for user interface elements
built with HTML, CSS, and JavaScript. It wraps your HTML experience and provides the ability to interact