The future looks like:
<html>
<head>
<title>My App</title>
<script src="enyo/enyo.js"></script>
<script src="source/package.js"></script>
</head>
<body class="enyo-unselectable">
<script>
new MyApp().renderInto(document.body);
</script>
</body>
</html>
That's it - nothing more
- Arbitrarily complex apps all look exactly the same
- We do not code HTML
- We do not code page-to-page
The future is objects
- Objects all the way down
- Components that draw themselves
- Components that contain other components
Sound familiar?
To see the future
We must embrace the past
What does old mean?
- Long ago
- It could be better
- It could be worse
- Age alone means nothing
Chronology
- Hypercard (1 meg Ram, Mac Plus, Bill Atkinson)
- Hypertext (HTML, Web, NextStep, Tim Berners-Lee)
- Webcrawler (DBKit, NextStep, Brian Pinkerton)
- WebKit / WebObjects (Bruce Ong, Nico Popp)
- Prototype / Scriptaculous (Javascript)
- Ajax (Web 2.0)
- Page-by-page Apps (jQuery Mobile)
- Single Page Apps (Enyo, Jo)
Hypercard
- App Creation for mere mortals
- Each card was a page
- Could link cards together in complex ways
- Distributed as shareware
- Self contained
Hypertext
- Note linking for half-mortals
- Not an application
- Link my diaries and notes to yours
- Endless connections using the Internet
- Not as slick as Hypercard, but far reaching
Webcrawler
- The first time someone made a Web App
- Dynamically produce HTML from user input
- Ridiculed (Useless, Bandwidth Hog)
- Changed the world, opened the door
WebKit / WebObjects
- App Creation for immortals
- "Gosh, we can use HTML as a remote interface to connect to databases!"
- Not full apps, half apps
- Click, wait, refresh, scroll, ... repeat
- Immortals can recreate apps like Webcrawler at whim
- Our livelihood was born
Prototype / Scriptaculous
- Javascript has nothing to do with Java
- Javascript has everything to do with LISP
- Unified Javascript programming for all browsers
- Taught us how to think in Javascript
- Gave us eye candy and effects
Ajax (Web 2.0)
- Half apps get a face lift
- Click, scroll, ... repeat (no wait, no refresh)
- Feels less like a website
- Feels more like a true application
Page-by-page Apps
- jQuery Mobile, Mojo (WebOS)
- Full Apps for the first time
- PhoneGap - puts you in mobile app stores
- Easy for web developers to jump into
- Hard for developers to be productive
- Leads to spaghetti code
- Thinking in pages, not as an application
Single Page Apps
- Full Apps developed as a desktop app
- No tag twiddling, no direct HTML
- Thinking only in Javascript
- App just performs on the Web
- Can target all devices
- Only way to target ChromeOS
What is WO missing?
- WOBuilder (Interface Builder) - I really miss that
- That slick "app" feel - we cannot get that without herculean effort
WO in the future
- Use EOF only - stop using WOComponents completely
- Cayenne is a good substitute - very similar to EOF
- Develop REST services
- Develop Single Page Apps in some other framework to consume REST
WebOS Framework Chronology
- Mojo / Ares
- Jo (Dave Balmer)
- Enyo / Ares
Palm -> HP -> LG -> Open Source
- Nobody thinks harder about Javascript apps than these guys
- It is truly free - not fake free
- They have a GUI IDE that really works
- Push button integration with PhoneGap
Why not Enyo / Ares?
- Lack of momentum - that's it
Yes indeed
- Hey, look at us, WO never had momentum either
- True genius is not always appreciated
- We make big bucks because we wield better tools
White man trick Indian once?
Shame on White man
White man trick Indian twice?
Shame on Indian
Read licenses carefully
- Only problem with commercial tools is that someday they may drop support and leave you hanging
- But if they are really good - the ride might be worth it anyway
- Life is uncertain, but all things being equal, go for open-source
Mojo example
<html>
<head>
<script src="/usr/palm/frameworks/mojo/mojo.js"></script>
</head>
<body>
<div class="palm-page-header">
<div class="title">
My First webOS App!
</div>
</div>
<button class="palm-button" id="my-awesome-button">
I'm an awesome button!
</button>
<div id="content">
Hello, world!<br/>
<img src="icon.png"/>
</div>
</body>
</html>
jQuery Mobile example
<html>
<head>
<link rel="stylesheet" href="jquery.mobile-1.4.5.min.css">
<script src="jquery-1.11.2.min.js"></script>
<script src="jquery.mobile-1.4.5.min.js">
</head>
<body>
<div data-role="page">
<div data-role="header">
<h1>Welcome To My Homepage</h1>
</div>
<div data-role="main" class="ui-content">
<p>I Am Now A Mobile Developer!!</p>
</div>
<div data-role="footer">
<h1>Footer Text</h1>
</div>
</div>
</body>
</html>
Mojo and jQuery Mobile
- Mojo was Palm only - with API to get to phone internals
- jQuery Mobile uses "data-role" for sugar
- Basically built apps in the same way
- You can write slick looking apps
- You will pick it up quick
- It will slow you down
Slow you down?
- Just as JSP and PHP are fast to learn
- The apps you make are strung together in brittle ways
- Fast to learn does not mean fast to develop
- As WO veterans, it's in our blood, we know this truth
Enyo:
<html>
<head>
<title>My App</title>
<script src="enyo/enyo.js"></script>
<script src="source/package.js"></script>
</head>
<body class="enyo-unselectable">
<script>
new MyApp().renderInto(document.body);
</script>
</body>
</html>
That is it?
- All Enyo apps have the same source output no matter their complexity
- Your "App" knows how to render itself
- You do not write any HTML
- You code in an IDE like InterfaceBuilder
- This is the gold standard, accept no less
- "Code that took about 2,000 lines in Mojo I could have done with about 1,000 lines in Enyo"
It is not magic
When your Javascript object renders itself it does something like:
document.write(
"<p style="color: blue;" id="helloworld">Hello, World!</p>"
);
But you will never write any of that yourself, just like you never write SQL because EOF handles that for you.
In Enyo you write this:
enyo.kind({
name: "HelloWorld",
kind: "Control",
tag: 'p',
content: 'Hello, World!',
style: 'color: blue'
});
Components and subcomponents
Enyo apps define one large control comprising the application's entire hierarchy of controls,
then render that into "document.body", replacing all the HTML that loaded with the page.
This makes the creation of new instances painless
var control2 = new HelloWorld({});
If we want to override our control's default content, we can explicitly declare a new value
var control2 = new HelloWorld({
content: "Hello, Everyone!"
});
Or we can change the content after creation:
control2.setContent("Goodbye, World!");
The same pattern applies to other properties, too. For instance, you could call
control2.setStyle("color: red");
and the "style" attribute would change, with the "styleChanged" method then being called.
Typically you'll use "addClass" and "applyStyle" instead, which are smart about how they adjust the style properties,
ensuring that changes made by other code is preserved. So this would be better:
control2.applyStyle("color", "red");
In Enyo, controls have many capabilities beyond simply rendering their own content.
Because a control may host other controls, it's possible for a single control to
contain a complex hierarchy of DOM elements. For example, we might have a control
that hosts a header and an unordered list with several list elements.
enyo.kind({
name: "HeaderList",
kind: "Control",
tag: "div",
components: [
{ tag: "p", content: "The Additive Primary Colors" },
{ tag: "ul", components: [
{ tag: "li", name: "red", content: "red" },
{ tag: "li", name: "green", content: "green" },
{ tag: "li", name: "blue", content: "blue" } ] } ]
});
Any component listed in a kind's "components" block will be added
to a special hash called "$", based on its name property. So, we could do:
var list = new HeaderList({});
list.$.red.applyStyle("color", "red");
list.$.green.applyStyle("color", "green");
list.$.blue.applyStyle("color", "blue");
Note, using the IDE even code completion will work on the dollar sign components.
Note that if you try to modify the "content" property of our "list" variable, nothing
will happen. For a component, having children takes precedence over having content.
In this case when the "list" component is rendered, you only get the content of the
children, not the "content" of the component.
Let us launch the Ares IDE
- install "node js" by downloading from http://nodejs.org
- install Ares by issuing the terminal command:
npm -d install ares-ide
- launch Ares by typing this in terminal:
~/node_modules/.bin/ares-ide -b
What will happen?
- We get a full blown IDE running in our web browser
- The IDE is written in Enyo so it is itself an example of what you can do
- It feels like WOBuilder / Interface Builder
- It works with Javascript and CSS
- Everything is live and we can build for any device with PhoneGap
Playing with Ares IDE:
- Let us make a simple "hello world" app
- Let us then experiment with an app that backs onto a REST service
Tid Bits regarding Enyo / Ares:
- Lots of pre-made components
- Easy to make an app that looks good
- Automatically looks great on desktops and mobile devices
- Components handle arbitrary large amounts of data fluidly
- Enyo apps feel like they were written in a native device framework
- Because then you are only targeting iOS
- If you wanted to do Android you'd have to maintain 2 codebases
- If you wanted something for the web, you'd have to maintain 3 codebases
- If what you make in Javascript looks so good, why even bother with native frameworks? Let the same app be accessible everywhere
Download the example projects