Luckily my goal of using only CSS and HTML for the initial page load styling turned out not to be a problem. Thanks to various new tags like
section(to encase each step in for semantic reasons) and new attributes on form elements like
openclass. Using that as a base, I decided to have transitions from one step to another occur by triggering a
nextStep()method which uses jQuery to find the step that has the
openclass, toggle that class off, go to the next section, and then toggle on the class there. This made the query simple in jQuery and allowed the transition code to be generic from step-to-step (although I had to add some hook support through jQuery.data() for step-specific prep and validation stuff).
That got me as far as having the web app function just like it did before I started this endeavour. But at this point I wanted to extend the potential audience, so I added iPhone support as well. This turned out to be basically simple, but I did have to tweak the UX just for the iPhone. When I designed the web app I was designing it for me while I am on my laptop, which means a full keyboard. I also made sure it worked on my adp1 (which is the developer version of the HTC Dream) which has a physical keyboard. And being somewhat of a UNIX geek, I made sure the entire web app could be driven from the keyboard under at least Google Chrome, from proper focus between form controls by pressing Enter, down to having your account password be in a text field that is already selected for easy cutting by hitting Cmd-X (or whatever your cut keyboard shortcut is). Nice and elegant and damn quick for getting your account password.
But the damn iPhone has no Enter key on its soft keyboard when you are filling out a form. Instead you get a "Go" button which acts as form submission. In my case that's useless as there is no place to submit the form to; everything is client-side for security reasons. That meant I had to tweak the UX so that you can not only press Enter to transition to the next step in Oplop, but you can also click the title of the next -- and only the next -- step as well to trigger a transition. In other words Oplop can be driven by a mouse now.
Since I was already adding UX support specifically because of the iPhone I figured I would also make the web app support being a web clip (web app that can be added to your home screen) as well. Thanks to Jonathan Stark's in-progress book on iPhone developement I made Oplop be zoomed in, have a proper home screen icon, and to ditch the location bar.
I would also like to thank ImageOptim while I am at it for being such a great little tool to optimize all the PNGs I have as icons (favicon, web clip icon, etc.).
So now I have a web app that works under (at least) Chrome, Safari (both desktop and Mobile), Firefox, and Android. I am rather happy with that browser coverage considering there is no magical browser detection stuff require, nor two versions of the web app.
But of course I am not finished yet. First thing is to write up some UX tests using Selenium 2/WebDriver and Jython. Now that everything is functioning as expected I want to keep it that way.
And then back to adding features! The next big ones will be adding offline web app support and creating a Google Chrome extension based on the web app. The former should be relatively straight-forward, but lead to some custom Mercurial hooks for properly updating the cache manifest (need to tweak the file every time something changes to trigger a new download of the app) and the latter should simply be fun as I think my planned approach will be more secure and have a better UX than the other password has algorithm extensions already available (if my idea works =).
Expect more blog posts on Oplop in the future as it is turning out to be a fun personal project. And if you actually use Oplop let me know and I will consider setting up a mailing list or something for Oplop-specific announcements (e.g. like the Python 3 command-line version I just uploaded to the project site) if there is enough users beyond just a handful of friends of mine.