Creating A Chrome App On a ChromeBook
When I first received a CR-48 back in December of last year, I mused on how it would be cool to be able to create Chrome Web Apps solely using a ChromeBook. Like the iPad before it, the ChromeBook was largely conceived as a device to consume content (save GDocs and such). More and more, Chrome web apps are changing that. In the last post, I noted some of the apps one could use as a developer to do dev work. In this post, I'll be taking it a bit further in using a stock ChromeBook to create a Chrome app.
Chrome OS's file manager gives you some limited copy, paste, and rename functions and the ability to create folders. Chrome OS doesn't allow you to create or edit individual files from the File Manager so we have to use HTML and JavaScript. This is not without reason. Even though the files in your Downloads directory can persist for a long time, Chrome can within reason purge those files if space is needed.
A Chrome web app (or extension or theme) is fairly simple to construct. It consists of a JSON file that describes metadata about the application, some HTML files, and some icon images. Chrome allows you to run a app or extension by pointing your browser to the directory holding your app. You can even package an application for deployment outside the Web Store as a crx file. To deploy an app to the Chrome Web Store, you need to upload a zip file of your application. Though beta and dev channel builds of Chrome OS give you the capability to extract zip files, they don't currently let you create zip files. Coupled with the limited file creation/editing options, we have to push those tasks to Cloud9.
Below is some inline CoffeeScript that I used to create some HTML text, store the base64 representations of a couple of icon images and create a JSON object. CoffeeScript has implicity typing and commas for a object that is properly indented and places one key-value pair on each line. To create the zip archive, I found a small JavaScript library called JSZip.
htmlText = "<html><head></head><body>sample extension html</body></html>"
a =
name: 'Sample Extension'
description: 'Created totally on Chrome OS'
version: '3'
icons:
"128": "HTML5_Badge_128.png"
"16": "HTML5_Badge_16.png"
app:
launch:
"local_path": "index.html"
img1 = "..." # truncated base64 text
img2 = "..." # truncated base64 text
Now that the assets have been created, we have to package them up into a zip file. JSZip can create either text or binary file entries using an optional map of attributes for the data. base64 and binary are the most commonly used. In the snippet below, I added the entries one by one to the zip file and used the location.href property to force the browser to download the generated archive. You're now set to upload it to the Chrome Web Store.
zip = new JSZip()
zip.add("manifest.json", JSON.stringify(a))
zip.add("index.html", htmlText)
zip.add("HTML5_Badge_128.png", img1, {base64: true, binary:true})
zip.add("HTML5_Badge_16.png", img2, {base64: true, binary:true})
content = zip.generate();
location.href="data:application/zip;base64,"+content;
I love Cloud9 but this is definitely a hack. A useful hack but a hack all the same. If I were planning to use this tactic for a productive solution, I would investigate the FileSystem APIs as they allow you to interact with the file system in a more natural way. It gives you a means to list files, create subdirectories, and append to files in a way that a regular browser does not. Adding and encoding each required image individually becomes unwieldy real fast.
It would be awesome to have an option to install a zipped Chrome app locally along the other Developer options. Just as AppInventor opens up the possibility for novices to create applications, I'm hoping that the community creates more means for people using ChromeBooks to be creators and not just consumers.