Is HTML5 a serious tool? – investigating the tech part 1

I have been doing a lot of reading about HTML5 and what it can and cannot do. There’s a lot of useful resources out there for this, some of which I mention in my HTML/HTML5 links here.  I’ve dipped into it a few times, and always felt the lack of anything useful across the main browsers made it a no go at that time.

What I’ve really been interested in is whether it’s actually usable now, and whether it’s come of age.  I’m really most interested in the potential on mobiles and tablets, to be honest.  And after a lot of reading where people kind of indicate it may be but give no concrete details, I’ve decided I need to investigate further.

My current plan – which is subject to change at any time – is to pursue the following investigative path:

  1. Figure out what bits of HTML5 are sufficiently cross-browser enough to be used for real apps
  2. Do the first part whilst considering not only desktops and laptops, but also tablets and phones
  3. Work up some sort of semi-trivial app that uses HTML5 and maybe other mainstream tech (such as cloud storage) to see how it fares on tablets and browsers – I’m thinking something like a to-do list or similar
  4. Work up some app that’s vaguely game-like or graphics-like to work out what the canvas tag might be useful for, in terms of business apps

 

I’ve started by working up a page that detects what and what isn’t available from your browser, and shows the results on screen. It doesn’t check for every possible HTML5 ability, but it does enough of the core ones that I think it’s pretty useful.

I used the following links to get to this point:

Here’s a link to this page. Everything it does is client-side, so you can just copy the source and use it where ever you want: What Can Your Browser Do?

I dropped in a suitable jQuery library, then from the 2 pages above I worked up the following code for detection and reporting:

Does the browser indicate storage is available? <br />
<div id=”indicateStorage” style=”left:10px”> Javascript is turned off, so test invalid</div>

<div id=”testStorage” style=”left:10px”> </div>
<div id=”testLocalStorage” style=”left:10px”> </div>
<div id=”testAudio” style=”left:10px”> </div>
<div id=”testAudioMP3″ style=”left:10px”> </div>
<div id=”testAudioWAV” style=”left:10px”> </div>
<div id=”testVideo” style=”left:10px”> </div>
<div id=”testCanvas” style=”left:10px”> </div>
<div id=”testFileAPI” style=”left:10px”> </div>
<div id=”testGeolocation” style=”left:10px”> </div>
<div id=”testOfflineWebApps” style=”left:10px”> </div>
<div id=”testIndexedDB” style=”left:10px”> </div>
<div id=”testWebSockets” style=”left:10px”> </div>
<div id=”testWebSQL” style=”left:10px”> </div>
<div id=”testWebWorkers” style=”left:10px”> </div>
<div id=”browserdetails” style=”left:10px”> </div>

<script lang=”javascript”>

function onload() {

var DetailsCounter = 0;

if (typeof (Storage) != “undefined”) {
$(“#indicateStorage”).html(“”);

for (var j = 1; j < 5; j++) {
sessionStorage.setItem(j, “hello” + j);
}

if (sessionStorage.length > 0) {
$(“#testStorage”).html(“Browser indicates session storage is happening”);
DetailsCounter += 1;
}
else {
$(“#testStorage”).html(“Browser indicates session storage is not happening”);
}

for (var j = 10; j < 15; j++) {
localStorage.setItem(j, “hellothere” + j);
}

if (localStorage.length > 0) {
$(“#testLocalStorage”).html(“Browser indicates local storage is happening”);
DetailsCounter += 2;

}
else {
$(“#testLocalStorage”).html(“Browser indicates local storage is not happening”);
}

}
else {
$(“#indicateStorage”).html(“Browser indicates session storage is not available”);
}

if (document.createElement(‘audio’).canPlayType) {
$(“#testAudio”).html(“Browser indicates audio available”);
DetailsCounter += 4;
}
else {
$(“#testAudio”).html(“Browser indicates audio not available”);
}
var a = document.createElement(‘audio’);

if (a.canPlayType && a.canPlayType(‘audio/mpeg;’).replace(/no/, ”)) {
$(“#testAudioMP3″).html(“Browser indicates MP3 audio available”);
DetailsCounter += 8;
}
else {
$(“#testAudioMP3″).html(“Browser indicates MP3 audio not available”);
}

if (a.canPlayType && a.canPlayType(‘audio/wav; codecs=”1″‘).replace(/no/, ”)) {
$(“#testAudioWAV”).html(“Browser indicates WAV audio available”);
DetailsCounter += 16;
}
else {
$(“#testAudioWAV”).html(“Browser indicates WAV audio not available”);
}

if (document.createElement(‘canvas’).getContext) {
$(“#testCanvas”).html(“Browser indicates Canvas available”);
DetailsCounter +=32;
}
else {
$(“#testCanvas”).html(“Browser indicates Canvas not available”);
}

if (document.createElement(‘video’).canPlayType) {
$(“#testVideo”).html(“Browser indicates video available”);
DetailsCounter += 64;
}
else {
$(“#testVideo”).html(“Browser indicates video not available”);
}
if (typeof FileReader != ‘undefined’) {
$(“#testFileAPI”).html(“Browser indicates File API available”);
DetailsCounter += 128;
}
else {
$(“#testFileAPI”).html(“Browser indicates File API not available”);
}
if (!!navigator.geolocation) {
$(“#testGeolocation”).html(“Browser indicates Geolocation available”);
DetailsCounter += 256;

}
else {
$(“#testGeolocation”).html(“Browser indicates Geolocation not available”);
}

if (!!window.applicationCache) {
$(“#testOfflineWebApps”).html(“Browser indicates Offline Web Apps available”);
DetailsCounter += 512;
}
else {
$(“#testOfflineWebApps”).html(“Browser indicates Offline Web Apps not available”);
}

if (!!window.indexedDB) {
$(“#testIndexedDB”).html(“Browser indicates IndexedDB available”);
DetailsCounter += 1024;
}
else {
$(“#testIndexedDB”).html(“Browser indicates IndexedDB not available”);
}

if (!!window.WebSocket) {
$(“#testWebSockets”).html(“Browser indicates Web Sockets available”);
DetailsCounter += 2048;
}
else {
$(“#testWebSockets”).html(“Browser indicates Web Sockets not available”);
}

if (!!window.openDatabase) {
$(“#testWebSQL”).html(“Browser indicates Web SQL available”);
DetailsCounter += 4096;
}
else {
$(“#testWebSQL”).html(“Browser indicates Web SQL not available”);
}

if (!!window.Worker) {
$(“#testWebWorkers”).html(“Browser indicates Web Workers available”);
DetailsCounter += 8192;
}
else {
$(“#testWebWorkers”).html(“Browser indicates Web Workers not available”);
}
var nVer = navigator.appVersion;
var nAgt = navigator.userAgent;
var browserName = navigator.appName;
var fullVersion = ” + parseFloat(navigator.appVersion);
var majorVersion = parseInt(navigator.appVersion, 10);
var nameOffset, verOffset, ix;

// In Opera, the true version is after “Opera” or after “Version”
if ((verOffset = nAgt.indexOf(“Opera”)) != -1) {
browserName = “Opera”;
fullVersion = nAgt.substring(verOffset + 6);
if ((verOffset = nAgt.indexOf(“Version”)) != -1)
fullVersion = nAgt.substring(verOffset + 8);
}
// In MSIE, the true version is after “MSIE” in userAgent
else if ((verOffset = nAgt.indexOf(“MSIE”)) != -1) {
browserName = “Microsoft Internet Explorer”;
fullVersion = nAgt.substring(verOffset + 5);
}
// In Chrome, the true version is after “Chrome”
else if ((verOffset = nAgt.indexOf(“Chrome”)) != -1) {
browserName = “Chrome”;
fullVersion = nAgt.substring(verOffset + 7);
}
// In Safari, the true version is after “Safari” or after “Version”
else if ((verOffset = nAgt.indexOf(“Safari”)) != -1) {
browserName = “Safari”;
fullVersion = nAgt.substring(verOffset + 7);
if ((verOffset = nAgt.indexOf(“Version”)) != -1)
fullVersion = nAgt.substring(verOffset + 8);
}
// In Firefox, the true version is after “Firefox”
else if ((verOffset = nAgt.indexOf(“Firefox”)) != -1) {
browserName = “Firefox”;
fullVersion = nAgt.substring(verOffset + 8);
}
// In most other browsers, “name/version” is at the end of userAgent
else if ((nameOffset = nAgt.lastIndexOf(‘ ‘) + 1) <
(verOffset = nAgt.lastIndexOf(‘/’))) {
browserName = nAgt.substring(nameOffset, verOffset);
fullVersion = nAgt.substring(verOffset + 1);
if (browserName.toLowerCase() == browserName.toUpperCase()) {
browserName = navigator.appName;
}
}
// trim the fullVersion string at semicolon/space if present
if ((ix = fullVersion.indexOf(“;”)) != -1)
fullVersion = fullVersion.substring(0, ix);
if ((ix = fullVersion.indexOf(” “)) != -1)
fullVersion = fullVersion.substring(0, ix);

majorVersion = parseInt(” + fullVersion, 10);
if (isNaN(majorVersion)) {
fullVersion = ” + parseFloat(navigator.appVersion);
majorVersion = parseInt(navigator.appVersion, 10);
}

document.write(”
+ ‘Browser name = ‘ + browserName + ‘<br>’
+ ‘Full version = ‘ + fullVersion + ‘<br>’
+ ‘Major version = ‘ + majorVersion + ‘<br>’
+ ‘navigator.appName = ‘ + navigator.appName + ‘<br>’
+ ‘navigator.userAgent = ‘ + navigator.userAgent + ‘<br>’
+ ‘Details = ‘ + DetailsCounter + ‘<br/>’
)

}

onload();

</script>

So, I now get a set of details about what is and isn’t active on the browser.  I can connect to the page on tablets, iPads, phones, desktops, whatever, and get some information about what HTML5 facilities are present.

If you want to find out more about this or see what else can be detected that  I haven’t included, check out Dive into HTML5 – Detecting HTML5 features.

You may also notice I have a variable incremented called ‘DetailsCounter’ that doesn’t appear to do much, but the plan is to use this value and the details about the browser/version/etc and send it via javascript call to an url where I then store the details in a database.

I’ll explain this next time, but with this page and the wired in database, I then intend to work up a simple-to-include javascript library that writes the browser abilities to a database, and helps me to decide what of the HTML5 facilities lend them to something like a mobile app that can continue to work off-line (or if something like that has enough common html5 functionality across all browsers/phones/tablets/etc to make it viable).

cheers
Mark Cain

Leave a Reply