HTML out of the Browser

Amongst my friends, I’m known as something of a Star Wars nerd. My longtime nick has been cfjedimaster (a combination of two passions, the other being ColdFusion), I work in a room packed to the gills with Star Wars toys, and I’ve actually gotten inked up twice now with Star Wars tats. That being said, it was another movie that had the most influence on my current career – Tron.

Tron_poster

I had already discovered an interest in computers before then, but it was Tron that really crystallized the idea for me. All of sudden I imagined myself being the programmer – creating intelligent programs and dominating the grid. Yeah, I know, I was a nerd back then too.

My dreams, though, ran into reality rather quickly during my time as a Comp Sci major in college. First – I discovered that “Hey, I’m good at math!” means crap all when you hit Calculus 3, and secondly, I discovered that I really wasn’t that interested in the performance of one sort versus another. I switched to English as a major (always a good choice) but kept messing around with computers. It was during this time that I was exposed to Mosaic and the early web.

I quickly jumped into the web as – well – I’ll put it bluntly – easier programming than what I had been exposed to before. I can remember LiveScript. I can remember my first Perl CGI scripts. This wasn’t exactly light cycle coding but it was simpler, fun, and actually cutting edge. I’ve spent a good chunk of my adult life now as a web developer, and while I certainly have delusions of the web being a pristine environment, it has been good to me (and millions of others) and I’m loving to see how much it evolves over time.

One of the most fascinating ways that web technologies have grown is outside of the web itself. In this article I’m going to look at all the various ways we can reuse our web-based technologies (HTML, JavaScript, and CSS) in non-web based environments. While it would be ludicrous to say that one shouldn’t learn other technologies, or that web standards work everywhere and in every situation, I feel strongly that the skills behind the web are ones open to a large variety of people in different disciplines – whether or not you got that PhD in computer science!

Mobile

This is typically the point where I’d discuss how important mobile is, but it’s 2014 and I think we’re past that now. Mobile development has typically involved either Java (Android) or Objective-C (iOS). Developers can also use web standards to build native applications. One solution is Apache Cordova (AKA PhoneGap).

Cordova uses a web view wrapped in a native application to allow web developers to build what are typically referred to as hybrid applications. Along with providing an easy way to get your HTML into an app, Cordova provides a series of different plugins that let you do more than what a typical web page can do on a device. So for example, you have easy access to the camera:

navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
    destinationType: Camera.DestinationType.DATA_URL
});
 
function onSuccess(imageData) {
    var image = document.getElementById('myImage');
    image.src = "data:image/jpeg;base64," + imageData;
}
 
function onFail(message) {
    alert('Failed because: ' + message);
}

You can also work with the accelerometer, GPS, contacts, the file system, and more. Cordova provides a JavaScript API that handles the communication to native code in the back end. Best of all, the same code can be used to build native applications for multiple different platforms (including Firefox OS, now supported in Cordova & PhoneGap).

To be clear, this isn’t a case of being able to take an existing web site and just package it up. Mobile applications are – by definition – completely different from a simple web site. But the fact that you can use your existing knowledge gives the developer a huge head start.

Another example of this (and one that is hopefully well known to readers of this site) is Firefox OS. Unlike Cordova, developers don’t have to wrap their HTML inside a web view wrapper. The entire operating system is web standards based. What makes Firefox OS even more intriguing is support for hosted applications. Firefox OS is a new platform, and the chance that your visitors are using a device with it is probably pretty slim. But with a hosted application I can easily provide support for installation on the device while still running my application off a traditional URL.

Consider a simple demo I built called INeedIt. If you visit this application in Chrome, it just plain works. If you visit it in a mobile browser on Android or iOS – it just works. But visit it with Firefox and code will trigger to ask if you want to install the application. Here is the block that handles this.

if(!$rootScope.checkedInstall && ("mozApps" in window.navigator)) {
 
    var appUrl = 'http://'+document.location.host+'/manifest.webapp';
    console.log('havent checked and can check');
    var request = window.navigator.mozApps.checkInstalled(appUrl);
 
    //silently ignore
    request.onerror = function(e) {
        console.log('Error checking install '+request.error.name);
    };
 
    request.onsuccess = function(e) {
        if (request.result) {
            console.log("App is installed!");
        }
        else {
            console.log("App is not installed!");
            if(confirm('Would you like to install this as an app?')) {
                console.log('ok, lets try to install');
                var installRequest = window.navigator.mozApps.install(appUrl);
 
                installRequest.onerror = function() {
                    console.log('install failure: '+this.error.name);
                    alert('Sorry, install failed.');
                };
 
                installRequest.onsuccess = function() {
                    console.log('did it');
                    alert('Thanks, app installed!');
                };
            }
            $rootScope.checkedInstall=true;
        }
    };
 
} else {
    console.log('either checked or non compat');
}

Pretty simple, right? What I love about this is that the code is 100% ignored outside of Firefox OS but automatically enhanced for folks using that operating system. I risk nothing – but I get the benefit of providing them a way to download and have my application on their device screen.

FF OS prompting you to install the app

Desktop

Of course, there are still a few people who sit in front of a gray box (or laptop) for their day to day work. Many desktop applications have been replaced by web pages, but there are still things that outside the scope of web apps. There are still times when a desktop app makes sense. And fortunately – there’s multiple ways of building them with web standards as well.

So you know the code example I just showed you? The one where Firefox OS users would be given a chance to install the application from the web page? That exact same code works on the desktop as well. While still in development (in fact, the application I built doesn’t work due to a bug with Geolocation), it will eventually allow you to push your web based application both to a mobile Firefox OS user as well as the other billion or so desktop users. Here’s the application installed in my own Applications folder.

INeedIt as a desktop app

As I said though – this is still relatively new and needs to bake a bit longer before you can make active use of it. Something you can use right now is Node Webkit. This open source project allows you to wrap Node.js applications in a desktop shell. Executables can than be created for Windows, Mac, and Linux. You get all the power of a “real” desktop application with the ease of use of web standards as your platform. There’s already a growing list of real applications out there making use of the framework – some I had even used before what realizing they used Node Webkit behind the scenes.

As an example, check out A Wizard’s Lizard, a RGP with random dungeons and great gameplay.

Screen shot - Wizard's Lizard

Native App Extensions

In the previous section we covered applications built with web standards. There are also multiple applications out there today, built natively, that can be extended with web standards. As a web developer you are probably already familiar with Firefox Add-Ons and Chrome extensions. There is an incredibly rich ecosystem of browser extensions for just about any need you can think of. What interests me however is the move to use web standards to open other products as well.

Did you know Photoshop, yes, Photoshop, now has the ability to extended with Node.js? Dubbed “Adobe Generator”, this extensibility layer allows for a script-based interface to the product. One example of this is the ability to generate web assets from layers based on a simple naming scheme. If you’ve ever had to manually create web assets, and update them, from a PSD, you will appreciate this. The entire feature though is driven by JavaScript and all makes use of a public API you can build upon. The code, and samples, are all available via GitHub.

Generator running within Photoshop

What Next?

Coming from the perspective of someone who has been in this industry for way too long, I can say that I feel incredibly lucky that web standards have become such a driving force of innovation and creativity. But it is not luck that has driven this improvement. It is the hard work of many people, companies, and organizations (like Mozilla) that have created the fertile landscape we have before us today. To continue this drive requires all of us to become involved, evangelize to others, and become proponents of a web created by everyone – for everyone.

About Raymond Camden

Raymond Camden is a developer for Adobe. His work focuses on client side development, mobile applications, Node.js and ColdFusion. He's a published author and presents at conferences and user groups on a variety of topics. Raymond can be reached at his blog (www.raymondcamden.com), @raymondcamden on Twitter, or via email at raymondcamden@gmail.com.

More articles by Raymond Camden…

About Robert Nyman [Editor emeritus]

Technical Evangelist & Editor of Mozilla Hacks. Gives talks & blogs about HTML5, JavaScript & the Open Web. Robert is a strong believer in HTML5 and the Open Web and has been working since 1999 with Front End development for the web - in Sweden and in New York City. He regularly also blogs at http://robertnyman.com and loves to travel and meet people.

More articles by Robert Nyman [Editor emeritus]…


14 comments

  1. Brett Zamir

    Haven’t read the whole article yet, but as far as Node Webkit, I am surprised by the relative lack of interest in my add-on AsYouWish (at https://github.com/brettz9/asyouwish/ ) which, if used in conjunction with Firefox profiles (to bring the rough equivalent of a separate executable), should, as far as I can tell, be able to get you all the same functionality, except that there is no need for special packaging and one can also hook into the many browser-specific APIs with user approval.

    April 17th, 2014 at 04:59

    1. Evert

      I would be deterred by anything that requires a separate add-on to work. Not to mention something that is specifically used for privilege escalation.

      April 17th, 2014 at 10:07

      1. Brett Zamir

        I understand it is not ideal to have a separate add-on (I wish this were standardized given how other potentially dangerous things are being allowed on user permission, esp. on mobile), but if an add-on is a problem, why are you then ok with a separate download for each version of a Node-Webkit app (not to mention the hassle for the developer in zipping the code on each modification) in an executable which does not inform you as to which exact privileges will be used, e.g., to destroy files, etc.?

        AsYouWish tells you exactly what privileges are being requested and escalates privileges only on apps you allow. It won’t even allow sites to ASK you for privs unless you whitelist them (or unless you whitelist protocols like https–though even here, you still need to approve the request before they can get any privilege escalation).

        April 17th, 2014 at 16:39

        1. Evert Pot

          If you are serious about wanting feedback about your project, you shouldn’t post a comment on a blogpost (you admitted didn’t even bother fully reading) that only mildly overlaps with what you’re doing.

          Now back to FirefoxOS and it’s installable apps. They actually still operate within a browser sandbox, unlike your tool.

          The additional privileged api’s they use, are really well defined apis, many of which are being turned into web standards.

          All of this will ‘just work’. and will not require a user to download any add-ons.

          Running an open source project that does not catch on is something I’m familiar with, and many others. If you’re looking for honest feedback, perhaps you should consider going to a forum or a subreddit and kindly ask for people’s opinions :)

          April 17th, 2014 at 16:52

          1. Brett Zamir

            I don’t think I was off topic: I admitted only reading the portion relevant to my comment in an article covering a variety of topics. My add-on was not only related to the topic mentioned but I thought ought would be of special interest to those already familiar with Mozilla’s own SDK APIs (this is a Mozilla blog after all) if not any Node.js APIs already within the SDK.

            But I do accept that other places would be better for full solicitation of feedback, so thank you for your suggestions on that. Your points are all well-taken, but 1) They are not addressing any specific advantages of the topic to which I was responding in the article, i.e., Node Webkit. and 2) They don’t address the immediate desirability for certain web apps to be able to access other APIs like arbitrary file reading or manipulation which are not standardized and may never be standardized.

            April 22nd, 2014 at 19:12

          2. Brett Zamir

            Oh, and as far as (network) sandboxing, I agree that would be useful for any HTML app to have (including especially AsYouWish ones), and have suggested it on the WhatWG list: http://comments.gmane.org/gmane.org.w3c.whatwg.discuss/41774

            April 22nd, 2014 at 19:45

  2. Raymond Camden

    Brett, your add-on creates executables?

    April 17th, 2014 at 08:59

    1. Brett Zamir

      @Raymond: No, my add-on allows websites on a whitelist (or, if you opt for it, from all websites matching a whitelist of protocols like https and file) to be able to ask you to grant any number of requested Addon SDK privileges (including chrome which will gives full XPCOM privs) which you can then approve or reject.

      I mention executables though because you can get an essentially equivalent effect by setting up an independent Firefox profile, and on Windows at least, you then set up a shortcut to that profile to have the profile get its own icon, you can then open that profile in a separate process. See:

      * http://kb.mozillazine.org/Shortcut_to_a_specific_profile
      * http://kb.mozillazine.org/Opening_a_new_instance_of_your_Mozilla_application_with_another_profile
      * http://kb.mozillazine.org/Bypassing_the_Profile_Manager

      You can then have that profile with only your privileged web app there by default (with AsYouWish installed on that profile or possibly installed globally for all profiles, if this is still working: http://kb.mozillazine.org/Installing_extensions#Global_installation ). The web app might be a pinned tab or just a single normal tab (with your options set to remember the last session so the tab will be there next time).

      A separate profile also lets you install only those add-ons that you are likely to need with that specialized web app. Unfortunately, I haven’t been able to figure out how to allow separate instances in the Windows task bar to create separate windows for the SAME profile, but different profiles is still better than nothing.

      I am, however, working on an add-on (not yet ready though) whose aim IS to build executables (or maybe it will just end up building batch files if they will do the trick): https://github.com/brettz9/executable-builder . Once it may be completed, it should automate the creation of the above-mentioned profile shortcuts and icons for those shortcuts (as well as be usable with another of my add-ons, WebAppFind, which allows you to open desktop files from the OS desktop (currently Windows only) directly into web apps, whether regular or AsYouWish-based ones).

      April 17th, 2014 at 16:19

      1. Patryk Zawadzki

        What if user clicks a link in such an “application”? Especially what if that link corresponds to a different application living in a separate browser profile?

        April 18th, 2014 at 00:59

        1. Brett Zamir

          @Patryk: The links in an AsYouWish-based app work just like links in any website, and they run in a browser tab just like any website; they can just get elevated JavaScript if the user agrees. If you want to force a specific profile to open, your AsYouWish app would need to utilize chrome privileges with nsIProcess, or perhaps better yet, the x-subprocess module, to invoke Firefox with the desired profile.

          But bear in mind that unless this is just for yourself, users might decide to use different names for their profiles, so you might not know in advance what the profile name was in which they stored the app.

          You could get around this by starting your own profile-naming convention, perhaps with a custom web-based protocol that could be used inside links for convenience.

          For example, an AsYouWish page could be registered to handle links such as “web+registeredprofilefinder:PatrykCalculator” such that, when clicked, the page would–upon user permission (see below on why)–start a subprocess to open a profile expected to be named “registered-PatrykCalculator” (before doing this, you could even use the Addons SDK used by AsYouWish to create the profile yourself if it didn’t exist, pin your app there or whatever).

          It is VERY, VERY important however, that, as with all AsYouWish apps, that no unwanted side effects should take place just by visiting the page in case a malicious site opens such links on your behalf (i.e., XSRF); your AsYouWish app could address this by confirming user permission any time a protocol/profile was about to be opened.

          April 22nd, 2014 at 19:40

  3. Adam

    Remember Mozilla Prism and Chromeless? It allowed us to create desktop apps from web apps. Why were there abandoned? Is there a simple way to create a standalone desktop app using Gecko engine, just like Brackets uses CEF? You can also embed a web view in Adobe AIR or JavaFX, but it’s WebKit, not Gecko.

    April 22nd, 2014 at 08:58

    1. Brett Zamir

      I would really like the answer to this too, but I will point out that one disadvantage of them is that one cannot use addons with them, user history, etc. They are separate from the user’s normal browser environment. That may be useful in some cases, of course, but I personally prefer the idea of leveraging separate profiles as one’s “executables” so one can get a separate process with its own environment.

      April 22nd, 2014 at 19:15

    2. Robert Nyman [Editor]

      On stand-alone apps across platforms, I recommend reading Progress report on cross-platform Open Web Apps.

      April 22nd, 2014 at 23:56

  4. Marco

    In Firefox 29 we’ve landed Desktop support for packaged apps too. There are probably still bugs (because the feature isn’t used so much), but I think it’s in a good shape.

    P.S.: The geolocation bug (actually a regression) was fixed recently.

    May 8th, 2014 at 13:55

Comments are closed for this article.