HTML5 Features on Tizen

1 Why HTML5 on Tizen?

In 2008 the W3C (World Wide Web Consortium) has started to work on HTML5 standard specification. In that time only PC browsers had implemented parts of HTML5 working draft. There were very little mobile devices that offered support for web based applications. The main reasons for that situation were:

  • HTML 4.01 was not sufficient to create UI for mobile devices
  • Device performance was not good enough to provide smooth UX for web based applications
  • HTML 4.01 didn’t provide web APIs that were comparable with the native APIs

From 2010 when new HTML5 drafts were published by W3C and the promising APIs, such as: Web Workers, Web Storage, Web Sockets and Geolocation API emerged. It becomes obvious for developers that HTML5 could be a good alternative for the mobile app development. Mobile devices are now efficient enough to run web browser with web application that runs almost as fast as native application. The most noticeable advantage of HTML5 based web applications is the cross-platform experience.

The example application screen shot

The sample application screen shot

2 Prerequisites

The example application utilizes following HTML5 APIs: Web Sockets, Web Storage, Web Workers. There are also code samples that demonstrate how to use HTML5 video element and API on Tizen. The example application is based on jQuery Mobile 1.2.0 framework that allows the user to create highly scalable web applications with intuitive and coherent user interface. To use jQuery Mobile, application must include jQuery 1.8.0 library. The sample application was tested on Tizen SDK 2.1.0.

TIP
In jQuery applications you can serialize JSON object to string using JSON.stringify(object) method. In order to deserialize string to JSON object use: $.parseJSON(string).
TIP
The jQuery Mobile framework is designed to handle web pages from the HTTP server via the HTTP protocol, while the Tizen application is served via FILE protocol. Due to this fact we recommend to turn off AJAX page requests as they will fail for FILE protocol. This difference is valid only for the page transitions in jQuery Mobile framework and not for all AJAX requests.

3 Selected HTML5 features on Tizen

HTML5 introduces not only the new tags for HTML, but also the new web APIs. The web APIs are defined in separate W3C documents. Attached examples show how to utilize some of the W3C Web APIs on Tizen.

Web Sockets allows the browser based applications to have full-duplex communication with the server that supports WS or WSS protocol. HTML4.01 introduced AJAX which is a one direction communication. With AJAX only the client is able to send requests to the server. When developers need to create, for example the chat application, the only way to do that was by polling requests via XHR. Now thanks to Web Sockets, developers are able to the attach listener event to be triggered as soon as a new message received from the server.

Web Storage is the storage area built in the browser. It can be used to store for example key value pairs by web applications or web sites. The storage area can be divided into:

  • The Local storage – this storage is available for any application regardless the browser session. It is removed when you uninstall the web application from the Tizen device.
  • The Session storage – storage that is kept only for lasting session

The local storage can be a great alternative for storing cookies or data in the file system. On Tizen, the size of the local storage is limited to 5MB per application, while there is no limit for the session storage . The Web Storage only accepts the string values. You need to serialize JSON objects to strings to store them using the web storage and de-serialize it when retrieving them.

Web Workers are the solution for web based applications to use multithreaded feature in web environment. They are mainly used for CPU intensive tasks to prevent application UI form being unresponsive. . Here is an example of using web worker: developer initializes a web worker with a JSON object, the web worker performs some calculations in a separate event loop and then it returns the results.

Touch events can be widely used by game developers to create highly responsive web games with 2D surface. There are 3 basic touch events defined in W3C specification:

  • touchstart: a finger is placed on a DOM element.
  • touchmove: a finger is dragged along a DOM element.
  • touchend: a finger is removed from a DOM element.

Touch events allow developers to detect how many touch points between the screen and user’s fingers are present on selected HTML element. It is possible to detect up to 3 touch points.

Thanks to the video tag and AV APIs, HTML5 also supports embedding the video and audio content in web applications..

JavaScript code snippets (HTML code is not included) in following part of the article are ready to be copy pasted into any application.

Web Sockets

There is a free echo web socket server - ws://echo.websocket.org available over WS protocol or WSS protocol - wss://echo.websocket.org available online. We will use them for our sample web socket apps. The sample Tizen application will connect to wss://echo.websocket.org echo server using WSS protocol and send messages. We create the JavaScript module tizenWebSocket to send messages.

var tizenWebSocket = (function (options) {
    var states, state, wsUri, output, websocket;

    states = {
        CONNECTED : 1,
        DISCONNECTED : 2,
        ERROR : 3
    };

    state = states.DISCONNECTED;

    wsUri = (options && options.server) ? options.server : "wss://echo.websocket.org/";

    output = function (txt) {
        $('#display').append("<div>" + txt + "</div>");
    };

    return {
        connect : function (callback) {
            var that = this;
            websocket = new WebSocket(wsUri);
            websocket.onopen = function (evt) {
                that.onOpen(evt);
                if (typeof callback === "function") {
                    callback();
                }
            };
            websocket.onclose = function (evt) {
                that.onClose(evt);
            };
            websocket.onmessage = function (evt) {
                that.onMessage(evt);
            };
            websocket.onerror = function (evt) {
                that.onError(evt);
            };

        },

        disconnect : function () {
            websocket.close();
        },

        onOpen : function () {
            output("CONNECTED");
            state = states.CONNECTED;
        },
        onClose : function () {
            output("DISCONNECTED");
            state = states.DISCONNECTED;
        },

        onMessage : function (evt) {
            output("RECEIVED: " + evt.data);
        },
        onError : function (evt) {
            output("ERROR: " + evt.data);
            state = states.ERROR;
        },

        /**
         * Sends message via web socket
         * @param txt {String} message to be sent
         * @returns {Boolean} true if successfully sent message, false otherwise
         */
        send : function (txt) {
            if (state === states.CONNECTED) {
                output("SEND: " + txt);
                websocket.send(txt);
                return true;
            } else {
                view.showPopup("Unable to send message");
                return false;
            }
        }
    };
}());

// connects with WS/WSS server
tizenWebSocket.connect(
    function () {
        // sends Hello message only when connected
        tizenWebSocket.send('Hello');
    }
);

Web Storage

This sample app shows you how to use the Web Storage feature. The user can add to and delete friend names from the list. The list can also be cleared . The sample app uses four basic local storage operations : add items, read and list all items, remove items, and clear whole local storage. In below example, 2 items are added to the local storage and displayed.

var item = { name : "Tom"};
var key = (new Date()).getTime();
localStorage.setItem(key, JSON.stringify(item));
var item = { name : "Carol" };
var key = (new Date()).getTime();
localStorage.setItem(key, JSON.stringify(item));

for (var i = 0; i < localStorage.length; i++) {
    var key = localStorage.key(i);
    var element = $.parseJSON(localStorage.getItem(key));
    console.log(element);
}

Web Workers

The web worker sample computes prime numbers in real time. Each time a new prime number is calculated and passed to the main event loop, then the corresponding DOM element is updated. This data flow was introduced because the web worker has no access to the DOM. webWorker.js code:

var running = false;

this.addEventListener('message', function (msg) {
    run();
}, false);

function run () {
    var n = 1, i;
    search: while (true) {
        n += 1;
        for (i = 2; i <= Math.sqrt(n); i += 1) {
            if (n % i === 0) {
                continue search;
            }
        }
        // found a prime!
        this.postMessage(n);
    }
}

Following JavaScript code is the main event loop code:

var worker = new Worker('./webWorker.js');
// in this event worker returns data
worker.addEventListener('message', function(msg) {
    console.log(msg.data);
}, false);
// empty message send to worker in order to start calculations
worker.postMessage();

Touch Events

Touch events recognizes how many user fingers touches selected DOM elements selected by users. Since touch events are primarily designed for touch enabled devices, below sample code will not work in regular PC browser. To utilize touch events, special JavaScript module touchEvents was developed.

touchEvents = (function ($) {
    var touch;

    return {
        setElement : function (id) {
            touch = document.getElementById(id);
        },

        bindEvents : function () {
            /**
             * Currently there is no possibility to bind touch events with
             * jQuery.bind method so we need to use pure ECMAScript
             * approach.
             */
            touch.addEventListener('touchmove', function () {
                $('#moving').text('YES');
            });

            touch.addEventListener('touchstart', function (ev) {
                var touchPoints = ev.targetTouches.length;
                if (touchPoints >= 3) {
                    $('#touchNo').text('3 or more fingers');
                } else {
                    $('#touchNo').text(touchPoints);
                }
            }, false);

            touch.addEventListener('touchend', function () {
                $('#touchNo').text('0 fingers');
                $('#moving').text('No');
            }, false);
        }
    };
}(jQuery));

// here we add myTouch element to body $('body').append('<div id="myTouch" style="width:200px;height:200px;background:#FF0000"> </div> '); // here we attach touch events to element touchEvents.setElement('myTouch');

Multimedia support

The HTML5 video tag is a powerful tool to embed multimedia content in Tizen web applications. The container used for the video file is MP4 in this sample. The video elementary stream is encoded using H.264 codec and audio elementary stream is encoded using AAC Audio. In the sample application, tizenVideo module utilizes HTML5 video element APIs to manipulate the video.

HTML5 code to embed video content:

<video id="video" width="360">
    <source src="./WebContent/samsung_challange.mp4">
</video>

Below tizenVideo module and sample code playbacks theabove video file.

 
tizenVideo = (function ($) {
    var videoInstance; 

    return {
        getVideoInstance : function () {
            return videoInstance;
        },

        setVideoInstance : function (id) {
            videoInstance = document.getElementById(id);
        },

        play : function () {
            videoInstance.play();
        },

        pause : function () {
            videoInstance.pause();
        },

        stop : function () {
            try {
                videoInstance.pause();
                videoInstance.currentTime = 0;
            } catch (e) {
                tlib.logger.err("Unable to stop the Video!");
            }
        },

        /**
         * Key binders method
         * @param elements {Object} JSON stores all available keys for which the actions can be hooked
         */
        bind : function (elements) {
            var that = this;
            elements.play.unbind().bind({
                click : function (event) {
                    event.preventDefault();
                    that.play();
                }
            });
            elements.stop.unbind().bind({
                click : function (event) {
                    event.preventDefault();
                    that.stop();
                }
            });
            elements.pause.unbind().bind({
                click : function (event) {
                    event.preventDefault();
                    that.pause();
                }
            });
            elements.fullscreen.unbind().bind({
                click : function (event) {
                    event.preventDefault();
                    that.fullscreen(true);
                }
            });
        },
        /**
         * Method used to turn on/off fullscreen mode for video
         * @param flag {Boolean} If true we turn one fullscreen mode otherwise we turn it off
         */
        fullscreen : function (flag) {
            var that = this;

            if (flag) {
                videoInstance.webkitEnterFullscreen();
                /**
                 * When we enter fullscreen mode we should handle some event to allow user
                 * to leave fullscreen mode, because browser doesn't do it automatically.
                 * We use either swipeLeft or swipeRight for this.
                 */
                $(document).bind('webkitfullscreenchange', function () {
                    $('html').bind({
                        swipeleft : function () {
                            tlib.logger.info("In FullScreen swipe left");
                            that.fullscreen(false);
                        },
                        swiperight: function () {
                            tlib.logger.info("In FullScreen swipe right");
                            that.fullscreen(false);
                        }
                    });
                });
            } else {
                document.webkitCancelFullScreen();
                $('html').unbind();
            }
        },
        /**
         * Method used to set callbacks
         * @param errorCB {Function} Callback invoked in case of playback error
         * @param endCB {Function} Callback invoked in case of playback end
         */
        setCallbacks : function (errorCB, endCB) {
            videoInstance.addEventListener('ended', endCB);
            videoInstance.addEventListener('error', errorCB);
        }
    };
}($));

// here we bind tizenVideo module with video element container
// that has id = video
tizenVideo.setVideoInstance('video');
// starts playback of video content
tizenVideo.play();
TIP Tizen launches web applications on the WebKit browser. There are dedicated methods available to launch video playback in the fullscreen mode: videoDOMElement.webkitEnterFullscreen(); To exit the fullscreen mode developer, should use: document.webkitCancelFullScreen();

Please keep in mind that the main difference is the support for the codecs regarding to the HTML5 video tag implementations in different browsers. The video file in the sample application is compatible with the Tizen WebKit web browser, but it was also tested to launch on Google Chrome 21.

4 Summary

From above samples, you probably notice that you can use HTML5 APIs in Tizen web apps pretty much in the same way as you used in your web sites. I believe if you have done some interesting HTML5 web apps, you can easily transfer them into Tizen web apps.

File attachments: