Yesterday’s webOS workshop, hosted at Pivotal Labs, provided an immersive learning experience for Ruby on Rails experts who were Web OS newbies. We required that everyone had installed the SDK in advance and verify their installation by building a very small sample project. I told people ahead of time that they would be turned away if they arrived unprepared. This ensured that all the participants were seriously interested in development and that we didn’t need to spend time on installation. With a relatively short introduction to webOS in the morning, I was impressed with the progress that people made on their apps in the afternoon. People mostly paired — some had planned to do so, but most spontaneously formed at the event. Many thanks to Palm and Pivotal for sponsoring the event and to all the volunteers who helped make it happen.
The hashtag was #webosworkshop.
Below are my very rough notes on the workshop, which I primarily wrote for my own reference, but I’m posting them here in case they help other folks who are just getting started with webOS.
These were the minimal command-line instructions that were needed to verify that participants were ready to code:
palm-emulator palm-package HelloWorld
Look for “id” in appinfo.json
$ cat HelloWorld/appinfo.json { "id": "com.mycompany.helloworld", "version": "1.0.0", "vendor": "My Company", "type": "web", "main": "index.html", "title": "HelloWorld", "icon": "icon.png" } palm-install com.mycompany.helloworld_1.0.0_all.ipk palm-launch com.mycompany.helloworld
webOS overview
Davis Frank (@dwfrank) gave an awesome overview of webOS specially tuned for Rails developers. He lead the Palm work at Pivotal Labs, where they have built Associated Press, LikeMe.net, and Tweed apps. He also wrote a clock app which is for sale for $1 — everyone should buy it, since he is saving up for a complete Beatles collection. I think he’s about half-way there.
* It’s like a server-side application but there is no request-response cycle
* everything else will be familiar
* HTML5 developers
* Webkit under the hood
In index.html, this is what includes the framework and makes it a WebOS app:
<script src="/usr/palm/frameworks/mojo/mojo.js" type="text/javascript" x-mojo-version="1" />
How is this like Rails MVC?
* Model: POJSOs (pronounced “poi-jos”)
* Views: Interpolated HTML files
* Controllers: Assistants (kinda, sort-of) It’s like WebOS has a controller and the assistant is the part that you can customize. The controller calls specific assistant APIs, it is the delegate that Palm’s controller uses to controll your app.
More notes:
* You don’t actually need to customize the assistant. That is the first thing that gets instantiated.
* Most of your apps will have just one stage. Multi-stage apps: email, apps w/ notification, dashboard panels.
* WebOS is a Linux-based OS w/ WebKit, close to the chrome branch of Webkit
What about testing?
There was no testing framework for webOS, so Pivotal created one. They looked at JSUnit (java), ScrewUnit (jquery, at the time didn’t work on WebOS, and other dependencies as well), JSpec — spent a week trying all of them and none worked, so they created Jasmine, a Javascript test framework, and Pockets, which drives the tests with rake tasks and webOS UI for reporting test results.
Jasmine
A Jasmine spec is just a javascript function
if ("should be able to ...", function () { ... });
There can be nested describes
describe("Something", function() { var whatever; beforeEach(function() { ... }) it("should..."
Any real test framework needs fakes
spyOn(whateverObject, 'doSomething'); ... expect(whateverObject.doSomething).wasCalled();
Pockets
Pockets integrates Jasmine into webOS.
pockets generate myapp
It creates a models directory to support MVC pattern, a plugins directory, and a test directory which mirrors your source code directory, just like in a Rails app.
Instead of maintaining sources.json by hand, it is automatically created when you build with the rake tasks. There is also a specific rake task to create it:
pockets sources [--production]
Live Coding
Davis built an app from scratch in a live coding demo. This made everything concrete in a fun way, and was the ideal prep for diving into webOS coding. Since pockets has not yet been released, you can’t follow these steps unless you got the gem at the workshop, but if you just want to browse the code, it is posted on github.
pockets generate jerry cd jerry rake test
Note: dashes in filenames — common in javascript, palm samples were that way, so pockets follows that convention
createFakeSceneAssistant(‘jerry’)
* common functions defined to do nothing
* creating a SceneAssistant in an environment
* for building a unit test of a scene assistant and mocking the world around it
* this tests the parts of your assistant that get executed when you call pushScene('jerry')
* what happens “under the hood” for both the createFakeSceneAssistant and real pushScene calls is that the string paramter (e,g ‘jerry’) is used to create the identifier (e.g. JerryAssistant) which is defined in javascript (jerry-assistant.js which is specified in sources.json)
Note:
* RubyMine live templates (to use them just type ‘assist’ and tab to get the assistant template and ‘jdesc’ for describe block and ‘jit’ for an it block.
* jsdocs for webOS recommended
this.controller.setupWidget('jerry')
All the UI elements, Palm calls widgets. You declare them in HTML. jerry-scene.html gets rendered when the jerry-scene is constructed. You declare a widget by making a div.
<div x-mojo-element="Button" id="buttonId" class="buttonClass" name="buttonName"/>
When we call setupWidget. It walks the dom and looks for widgets (e.g. setupWidget(‘quotes’) looks for a div with id=”quotes”). You can look at the actual dom by running with the -i option and using the inspector tool, which will let you modify css selectors and such. However, try not the think about the DOM below the widget.
The second param to setupWidget is a hash of attributes and the third param is your model, which in the case of a list is expected to have an ‘items’ property (although you can specify an alternate name.) You need to look at the API for each widget to know exactly what to parameters are expected.
__defineGetter__ and __defineSetter__ from JavaScript 1.5
forEach — usually native iterator
rememmber: var self = this; before calling forEach
then we can refer to self in the middle of the each
1.3.5 = WebKit3, close to Safari 3.2
1.4 (in beta) = WebKit4
test with Chrome or Safari
in order to enable developer mode, type one of these special commands into the universal search:
* upupdowndownleftrightleftrightbastart (konami code)
* webos20090606
Protype’s interpolation escapes its contents, use minus if you have actual HTML content that you want to add:
#{-
palm launch -i (launches in inspect mode)
palm-log -f com.mycompany.myapp
tails just your app’s part of the log
tips and tricks
* JS isn’t afraid of Objects & Patterns. Read Javascript: the good parts
* APIs deserve objects (e.g. twitter_api.doSomething)
Skinny Controller, Fat Model applies. In webOS, that is: Skinny *Assistant*, Fat Model
use: this.controller.sceneElement
instead of: this.controller.get and this.controller.select
use
* sceneElement.querySelector
* sceneElement.querySelectorAll
allows you to put hashes and dots
allows you to name your classes well enough to index into your dom
you are scoping your search in your scene
you can use jQuery (although you will need to know a couple of hacks to get it to work)
if you have to parse XML, jQuery is hot
css selectors really help you: know your nthchild, first child
css for scenes: make sure to scope all the css to that scene
always add a class to override built-in behaviors
Use the Mojo source: simlink into the SDK, the IDE will index the mojo source, can click in and see what the source code is doing really, good learning tool, nice JS tricks
Project Ares
Matt McNaulty showed a web-based app development tool set, called Project Ares. It has a pretty nice drag-and-drop GUI tool kit, that supports advanced Layout and event handling, plus a full code editor, based on Mozilla’s Bespin project, and a full debugger. You can start on the command-line and import an app into Ares if you want. It works with svn and mercurial — git support is planned. You need to use Safari, FF 3.5 +, Chrome on the mac doesn’t have java
This seems very cool and part of an emerging trend. More and more development is moving to the web. Originally planned as a way to broaden the audience of developers to people not comfortable with the command line or eclipse, they are finding the Ares appeals to a lot of experienced developers who can use the other tools, but prefer Ares.
Questions?
What about persistence? depot APIs, no real ORM yet
persistence of app data off the phone? not backed up (yet). HTML5′s db content for the web browser (and Palm’s built-in apps) does get backed up.
Note: Depot is just a wrapper around HTML5
You can pull any app of the phone and look at the source, but I didn’t catch exactly how to do this