Add assets for WML to HTML transformation using XSLT.

Change-Id: I8777f2409217e92b19a33d1afc32ce9ca0b7608e
diff --git a/assets/wml/swe_wml.css b/assets/wml/swe_wml.css
new file mode 100755
index 0000000..f8e6085
--- /dev/null
+++ b/assets/wml/swe_wml.css
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+p {
+    word-wrap: break-word;
+}
+
+form {
+    display:inline;
+    margin-top: 0em;
+    margin-bottom: 0em;
+}
+
+img {
+  max-width: 100%;
+  max-height: 100%;
+  width: auto;
+  height: auto;
+}
+
+.wml_card
+{
+    display:none;
+}
+
+.wml_body
+{
+    background:#dddddd;
+    margin:4px;
+}
+
+.wml_card_title
+{
+    background:#777777;
+    border-top:2px solid #777777;
+    border-top-right-radius: 10px;
+    border-top-left-radius: 10px;
+    padding:5px;
+    color:white;
+    font-weight: bold;
+}
+
+.wml_card_content
+{
+    border-left:2px solid #777777;
+    border-right:2px solid #777777;
+    border-bottom:2px solid #777777;
+    padding:10px 20px;
+    background:#ffffff;
+    border-bottom-right-radius: 10px;
+    border-bottom-left-radius: 10px;
+}
+
+.wml_onevent
+{
+    display:none;
+}
diff --git a/assets/wml/swe_wml.js b/assets/wml/swe_wml.js
new file mode 100755
index 0000000..92fa6ee
--- /dev/null
+++ b/assets/wml/swe_wml.js
@@ -0,0 +1,649 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+var cardElements;
+var currentActiveCard = null;
+var defaultActiveCard = null;
+// Forward navigation >= 0, backward navigation == -1, unknown navigation == -2
+var currentNavigationType = -2;
+var blankRegEx = /^\s*$/;
+
+var WMLBrowser = {
+    name: "WMLBrowserContext",
+    variables: new Object(),
+    setVar: function (key, value) {
+        this.variables[key] = value;
+    },
+    getVar: function (key) {
+        var value = this.variables[key];
+        if (value == null)
+            value = '';
+        return value;
+    },
+    newContext: function () {
+        this.variables = new Object();
+    },
+}
+
+function isBlank(str) {
+    return (!str || blankRegEx.test(str));
+}
+
+function isURLHash(str) {
+    return (!isBlank(str) && str.length > 1 && str.indexOf("#") == 0);
+}
+
+function getIdFromURLHash(hash) {
+    return hash.substr(1);
+}
+
+window.onhashchange = function()
+{
+    console.log("window.onhashchange currentNavigationType = " + currentNavigationType);
+    var newHash = window.location.hash;
+    if (!isURLHash(newHash)) {
+        currentActiveCard.style.display = "none";
+        defaultActiveCard.style.display = "initial";
+        currentActiveCard = defaultActiveCard;
+    } else {
+        showCardById(newHash.substr(1));
+    }
+    updateWMLVariables();
+    scheduleTimerTaskIfNeeded(currentActiveCard);
+    handleOnNavigationIntrinsicEvent();
+};
+
+window.onload = function()
+{
+    // Consider all the load/reload on this deck as forward navigation.
+    currentNavigationType = 1;
+    var cardHash = window.location.hash;
+    console.log("window.onload card = " + cardHash);
+    cardElements = document.getElementsByClassName('wml_card');
+    defaultActiveCard = cardElements[0];
+    // All the cards are hidden by default.
+    // Show the active card onload.
+    if (isURLHash(cardHash)) {
+        var cardId = cardHash.substr(1);
+        for(var i=0, l=cardElements.length; i<l; i++) {
+            var card = cardElements[i];
+            if (card.getAttribute("id") == cardId) {
+                currentActiveCard = card;
+                currentActiveCard.style.display = "initial";
+                break;
+            }
+        }
+    }
+    if (!currentActiveCard) {
+        currentActiveCard = defaultActiveCard;
+        currentActiveCard.style.display = "initial";
+    }
+    replaceVariablesInTextContentBySpan();
+    fixTextContentInAnchorTasks();
+    initializeSelectElements();
+    scheduleTimerTaskIfNeeded(currentActiveCard);
+    handleOnNavigationIntrinsicEvent();
+};
+
+function showCardById(cardId, onload)
+{
+    if (currentActiveCard && currentActiveCard.getAttribute("id") == cardId) {
+        // We have nothing to do.
+        return false;
+    }
+    for(var i=0, l=cardElements.length; i<l; i++) {
+        var card = cardElements[i];
+        if (card.getAttribute("id") == cardId) {
+            currentActiveCard.style.display = "none";
+            currentActiveCard = card;
+            currentActiveCard.style.display = "initial";
+            return true;
+        }
+    }
+    return false;
+}
+
+function handleOnNavigationIntrinsicEvent() {
+    var navigationType = currentNavigationType;
+    currentNavigationType = -2;
+
+    if (navigationType >= 0) {
+        executeOnenterforwardTask();
+    } else if (navigationType == -1) {
+        executeOnenterbackwardTask();
+    } else {
+        console.log("WARNING: Cannot determine the navigation event type on this card!");
+    }
+}
+
+////////////////////////// WML Variables ////////////////////////////////////////
+function replaceVariablesInTextContentBySpan()
+{
+    var pattern1 = /(\$\(([_a-z]{1}[_a-z0-9]*)([:]{1}((([e]{1})(scape)?)|(([n]{1})(oesc)?)|(([u]{1})(nesc)?)))?\))/gi;
+    var pattern2 = /(\$([_a-zA-z]{1}[_a-zA-Z0-9]*))/g;
+    var whitespace = /^\s*$/g;
+    var replacer = function () {
+        var name = arguments[2];
+        var escape = "";
+        if (arguments[12])
+            escape = arguments[12];
+        else if (arguments[9])
+            escape = arguments[9];
+        else if (arguments[6])
+            escape = arguments[6];
+        var wml_variable_span = "\<span\ data\-wml\_name\=\"" + name + "\"\ class\=\"wml_variable\" data\-wml\_escape\=\"" + escape + "\"\>\<\/span\>";
+        console.log("replaceVariablesInTextContentBySpan() Found variable " + arguments[0]);
+        return wml_variable_span;
+    };
+
+    var textNodes = [];
+    var treeWalker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null, false);
+    while(treeWalker.nextNode()) {
+        textNodes.push(treeWalker.currentNode);
+    }
+
+    for(var i=0, l=textNodes.length; i<l; i++) {
+        var curNode = textNodes[i];
+        var text = curNode.nodeValue;
+        if (!(whitespace.test(text))) {
+            var replaced = false;
+            if (pattern1.test(text)) {
+                text = text.replace(pattern1, replacer);
+                replaced = true;
+            }
+            if (pattern2.test(text)) {
+                text = text.replace(pattern2, replacer);
+                replaced = true;
+            }
+            if (replaced) {
+                var mySpan = document.createElement("span");
+                mySpan.innerHTML = text;
+                curNode.parentNode.replaceChild(mySpan, curNode);
+            }
+        }
+    }
+}
+
+////////////////////////// WML Anchor Tasks ////////////////////////////////////////
+// TODO: Optimize this brutal code
+function fixTextContentInAnchorTasks()
+{
+    var anchorTasks = document.getElementsByClassName('wml_anchor_task');
+    for(var i=0, l=anchorTasks.length; i<l; i++) {
+        var container;
+        var taskParent;
+        var task = anchorTasks[i];
+        if (task.dataset.wml_task_type == 'wml_task_go') {
+            taskParent = task.parentNode;
+            container = taskParent.parentNode;
+        } else {
+            taskParent = task;
+            container = task.parentNode;
+        }
+        container.removeChild(taskParent);
+        var anchorText = container.innerHTML;
+        while (container.firstChild) {
+            container.removeChild(container.firstChild);
+        }
+        container.appendChild(taskParent);
+        console.log("fixTextContentInAnchorTasks: anchorText = " + anchorText);
+        task.innerHTML = anchorText + task.innerHTML;
+    }
+}
+
+////////////////////////// WML Timer ////////////////////////////////////////
+var activeScheduledTimer = null;
+function scheduleTimerTaskIfNeeded(card)
+{
+    var timerElements = card.getElementsByClassName('wml_timer');
+    if (timerElements.length > 0) {
+        var timeout = timerElements[0].dataset.wml_value;
+        activeScheduledTimer = window.setTimeout(executeTimerTask, timeout * 100);
+        console.log("Starting WML timer timeout = " + timeout);
+    }
+}
+
+function cancelScheduledTimerTask()
+{
+    if (activeScheduledTimer != null) {
+        window.clearTimeout(clearTimeout);
+        activeScheduledTimer = null;
+    }
+}
+
+////////////////////////////////// <select> & <option> ////////////////////////
+var multiSelectSeparator = ";";
+var selectElementsMap = new Object();
+var WMLSelectElements = {
+    name: "WMLSelectElementsList",
+    options: new Object(),
+    setSelectedOptions: function (key, options) {
+        this.options[key] = options;
+    },
+    getSelectedOptions: function (key) {
+        return this.options[key];
+    },
+};
+
+function initializeSelectElements()
+{
+    var selectElements = document.getElementsByClassName('wml_select');
+    for(var i=0, l=selectElements.length; i<l; i++) {
+        var select = selectElements[i];
+        var iname = select.dataset.wml_iname;
+        // Preselect options based on 'ivalue'
+        var ivalue = select.dataset.wml_ivalue;
+        if (!isBlank(ivalue)) {
+            var options = select.options;
+            var optionsCount = options.length;
+            var ivalueList = ivalue.split(multiSelectSeparator);
+            for(var j=0, ll=ivalueList.length; j<ll; j++) {
+                var index = parseInt(ivalueList[j], 10);
+                if (index > 0 && index <= optionsCount) {
+                    options[index-1].selected = 'selected';
+                }
+            }
+        }
+
+        // Keep a copy of selected options to process 'onpick' events
+        var options = select.selectedOptions;
+        var optionsCount = options.length;
+        var optionsList = [];
+        for(var j=0; j<optionsCount; j++) {
+            optionsList.push(options[j]);
+        }
+        var uniqueId = "wml_select_" + i;
+        select.dataset.wml_unique_id = uniqueId;
+        WMLSelectElements.setSelectedOptions(uniqueId, optionsList);
+    }
+}
+
+function handleSelectOnchangeEvent(select)
+{
+    refreshVariableInSelectElement(select);
+    var options = select.selectedOptions;
+    var optionsCount = options.length;
+    var uniqueId = select.dataset.wml_unique_id;
+    var oldSelectedOptions = WMLSelectElements.getSelectedOptions(uniqueId);
+
+    // Update the copy of selected options before we do anything
+    var optionsList = [];
+    for(var j=0; j<optionsCount; j++) {
+        optionsList.push(options[j]);
+    }
+    WMLSelectElements.setSelectedOptions(uniqueId, optionsList);
+
+    // process 'onpick' events if needed
+    for(var i=0; i<optionsCount; i++) {
+        var option = options[i];
+        var onpick = option.dataset.wml_onpick;
+        if (!isBlank(onpick)) {
+            var selectedNewly = true;
+            for(var j=0; j<oldSelectedOptions.length; j++) {
+                if (option.isSameNode(oldSelectedOptions[j])) {
+                    selectedNewly = false;
+                    break;
+                }
+            }
+            if (selectedNewly) {
+                internal_executeOnpickTask(option);
+                return;
+            }
+        }
+    }
+}
+
+function handleAOnClick(event, node)
+{
+    var href = node.href;
+    var search = node.search;
+    console.log("handleAOnClick <a> href = " + href);
+    refreshVariablesInControlElements();
+    if (!isBlank(search)) {
+        node.search = substituteVariablesInURL(search);
+    } else {
+        node.href = href.split("?")[0];
+    }
+    event.preventDefault();
+    navigateToURL(node.href);
+    return false;
+}
+
+//////////////////////// Variables /////////////////////////
+function substituteVariablesInURL(url)
+{
+    var pattern = /(((\%24)|(\$))\(([_a-z]{1}[_a-z0-9]*)([:]{1}((([e]{1})(scape)?)|(([n]{1})(oesc)?)|(([u]{1})(nesc)?)))?\))/gi;
+    var replacer = function () {
+        var name = arguments[2];
+        // TODO: Do the URL escaping here
+        console.log("substituteVariablesInURL() found variable : " + arguments[0]);
+        return WMLBrowser.getVar(name);
+    };
+    return url.replace(pattern, replacer);
+}
+
+function substituteVariablesInPostfield(value)
+{
+    var pattern = /(\$\(([_a-z]{1}[_a-z0-9]*)([:]{1}((([e]{1})(scape)?)|(([n]{1})(oesc)?)|(([u]{1})(nesc)?)))?\))/gi;
+    var replacer = function () {
+        var name = arguments[2];
+        // TODO: Do the URL escaping here
+        console.log("substituteVariablesInPostfield() found variable : " + arguments[0]);
+        return WMLBrowser.getVar(name);
+    };
+    return value.replace(pattern, replacer);
+}
+
+function refreshVariableInSelectElement(select)
+{
+    var options = select.selectedOptions;
+    var value = "";
+    var ivalue = "";
+    var optionsCount = options.length;
+    if (optionsCount > 0) {
+        var op = options[0];
+        value = op.value;
+        ivalue = (op.index + 1);
+        for(var i=1; i<optionsCount; i++) {
+            op = options[i];
+            value += multiSelectSeparator + op.value;
+            ivalue += multiSelectSeparator + (op.index + 1);
+        }
+    }
+    var name = select.name;
+    if (!isBlank(name)) {
+        WMLBrowser.setVar(name, value);
+        console.log("refreshVariableInSelectElement name = " + name + ", value = " + value);
+    }
+    var iname = select.dataset.wml_iname;
+    if (!isBlank(iname)) {
+        if (isBlank(ivalue)) {
+            // An index of zero indicates that no option is selected.
+            ivalue = "0";
+        }
+        WMLBrowser.setVar(iname, ivalue);
+        console.log("refreshVariableInSelectElement iname = " + iname + ", ivalue = " + ivalue);
+    }
+}
+
+function refreshVariablesInControlElements()
+{
+    var inputElements = currentActiveCard.getElementsByClassName('wml_input');
+    for(var i=0, l=inputElements.length; i<l; i++) {
+        var input = inputElements[i];
+        WMLBrowser.setVar(input.name, input.value);
+        console.log("refreshVariablesInControlElements <input> name = " + input.name + ", value = " + input.value);
+    }
+
+    var selectElements = currentActiveCard.getElementsByClassName('wml_select');
+    for(var i=0, l=selectElements.length; i<l; i++) {
+        var select = selectElements[i];
+        refreshVariableInSelectElement(selectElements[i]);
+    }
+}
+
+function updateVariableInPostfields(form)
+{
+    var postfields = currentActiveCard.getElementsByClassName('wml_postfield');
+    for(var i=0, l=postfields.length; i<l; i++) {
+        var input = postfields[i];
+        input.value = substituteVariablesInPostfield(input.value);
+        console.log("updateVariableInPostfields <postfield> name = " + input.name + ", value = " + input.value);
+    }
+}
+
+/////////////// Navigation ////////////////////
+function navigateToURL(url)
+{
+    console.log("navigateToURL: url = " + url);
+    cancelScheduledTimerTask();
+    currentNavigationType = 1;
+    window.location = url;
+}
+
+function navigateToCard(card)
+{
+    console.log("navigateToCard: card = " + card);
+    cancelScheduledTimerTask();
+    currentNavigationType = 1;
+    window.location.hash = card;
+}
+
+function navigateBack()
+{
+    console.log("navigateBack: currentState = ");
+    console.log(window.history.state);
+    cancelScheduledTimerTask();
+    currentNavigationType = -1;
+    window.history.back();
+}
+
+////////////// WML Tasks //////////////////////
+//<refresh>
+
+function updateWMLVariables()
+{
+    var wmlVariables = currentActiveCard.getElementsByClassName('wml_variable');
+    for(var i=0, l=wmlVariables.length; i<l; i++) {
+        var varElement = wmlVariables[i];
+        // Handle the variable escaping option here
+        var value = WMLBrowser.getVar(varElement.dataset.wml_name);
+        // TODO: Handle nested variable substitution on 'value'
+        var conversion = varElement.dataset.wml_escape;
+        if (!isBlank(value) && !isBlank(conversion)) {
+            if (conversion == "e" || conversion == "E") {
+                value = encodeURIComponent(value);
+            } else if (conversion == "u" || conversion == "U") {
+                value = decodeURIComponent(value);
+            }
+        }
+        varElement.innerHTML = value;
+    }
+}
+
+function internal_executeRefreshTask(root)
+{
+    console.log("internal_executeRefreshTask");
+    var setvarElements = root.getElementsByClassName('wml_setvar');
+    for(var i=0, l=setvarElements.length; i<l; i++) {
+        var setvar = setvarElements[i];
+        WMLBrowser.setVar(setvar.dataset.wml_name, setvar.dataset.wml_value);
+        console.log("<setvar> " + setvar.dataset.wml_name + " = " + setvar.dataset.wml_value);
+    }
+    updateWMLVariables();
+}
+
+function executeRefreshTask(event, node)
+{
+    event.preventDefault();
+    internal_executeRefreshTask(node.parentNode);
+    return false;
+}
+
+// <prev>
+function internal_executePrevTask(node)
+{
+    console.log("internal_executePrevTask");
+    internal_executeRefreshTask(node.parentNode);
+    navigateBack();
+}
+
+function executePrevTask(event, node)
+{
+    event.preventDefault();
+    internal_executePrevTask(node);
+    return false;
+}
+// <option onpick="...">
+function internal_executeOnpickTask(option)
+{
+    var href = option.dataset.wml_onpick;
+    console.log("internal_executeOnpickTask href = " + href);
+    //internal_executeRefreshTask(option.parentNode);
+    //refreshVariablesInControlElements();
+    if (isURLHash(href)) {
+        navigateToCard(href);
+        return true;
+    }
+    navigateToURL(href);
+    return true;
+}
+
+//<go>
+function internal_executeGoTask(form)
+{
+    var href = form.dataset.wml_href;
+    console.log("internal_executeGoTask href = " + href);
+    internal_executeRefreshTask(form.parentNode);
+    refreshVariablesInControlElements();
+    if (isURLHash(href)) {
+        navigateToCard(href);
+        return true;
+    }
+    // Substitute variables in <postfield> 'value' attributes before form submission.
+    updateVariableInPostfields();
+    form.submit();
+    return false;
+}
+
+function executeGoTask(event, form)
+{
+    event.preventDefault();
+    internal_executeGoTask(form);
+    return false;
+}
+
+//<onevent>
+function executeTimerTask()
+{
+    console.log("executeTimerTask()");
+    activeScheduledTimer = null;
+    // Handle <card ontimer="..."> event first
+    var ontimer = currentActiveCard.dataset.wml_ontimer;
+    if (!isBlank(ontimer))
+    {
+        navigateToURL(ontimer);
+        return;
+    }
+    // Handle <onevent type="timer">... here
+    var tasks = currentActiveCard.getElementsByClassName('wml_onevent_ontimer');
+    if (tasks.length > 0) {
+        var onevent = tasks[0];
+        if (onevent.dataset.wml_task_type == 'wml_task_go')
+            return internal_executeGoTask(onevent);
+        else if (onevent.dataset.wml_task_type == 'wml_task_refresh')
+            return internal_executeRefreshTask(onevent);
+        else if (onevent.dataset.wml_task_type == 'wml_task_prev')
+            return internal_executePrevTask(onevent);
+        else if (onevent.dataset.wml_task_type == 'wml_task_noop')
+            return;
+    }
+    // Handle <template timer="..."> event at the end
+    var templates = currentActiveCard.getElementsByClassName('wml_template');
+    if (templates.length > 0) {
+        var ontimer = templates[0].dataset.wml_ontimer;
+        if (!isBlank(ontimer))
+        {
+            navigateToURL(ontimer);
+            return;
+        }
+    }
+}
+
+function executeOnenterforwardTask()
+{
+    console.log("executeOnenterforwardTask()");
+    // Handle <card onenterforward="..."> event first
+    var onef = currentActiveCard.dataset.wml_onenterforward;
+    if (!isBlank(onef))
+    {
+        navigateToURL(onef);
+        return;
+    }
+    // Handle <onevent type="onenterforward">... here
+    var tasks = currentActiveCard.getElementsByClassName('wml_onevent_onenterforward');
+    if (tasks.length > 0) {
+        var onevent = tasks[0];
+        if (onevent.dataset.wml_task_type == 'wml_task_go')
+            return internal_executeGoTask(onevent);
+        else if (onevent.dataset.wml_task_type == 'wml_task_refresh')
+            return internal_executeRefreshTask(onevent);
+        else if (onevent.dataset.wml_task_type == 'wml_task_prev')
+            return internal_executePrevTask(onevent);
+        else if (onevent.dataset.wml_task_type == 'wml_task_noop')
+            return;
+    }
+    // Handle <template onenterforward="..."> event at the end
+    var templates = currentActiveCard.getElementsByClassName('wml_template');
+    if (templates.length > 0) {
+        var onef = templates[0].dataset.wml_onenterforward;
+        if (!isBlank(onef))
+        {
+            navigateToURL(onef);
+            return;
+        }
+    }
+}
+
+function executeOnenterbackwardTask()
+{
+    console.log("executeOnenterbackwardTask()");
+    // Handle <card onenterforward="..."> event first
+    var oneb = currentActiveCard.dataset.wml_onenterbackward;
+    if (!isBlank(oneb))
+    {
+        navigateToURL(oneb);
+        return;
+    }
+    // Handle <onevent type="onenterbackward">... here
+    var tasks = currentActiveCard.getElementsByClassName('wml_onevent_onenterbackward');
+    if (tasks.length > 0) {
+        var onevent = tasks[0];
+        if (onevent.dataset.wml_task_type == 'wml_task_go')
+            return internal_executeGoTask(onevent);
+        else if (onevent.dataset.wml_task_type == 'wml_task_refresh')
+            return internal_executeRefreshTask(onevent);
+        else if (onevent.dataset.wml_task_type == 'wml_task_prev')
+            return internal_executePrevTask(onevent);
+        else if (onevent.dataset.wml_task_type == 'wml_task_noop')
+            return;
+    }
+    // Handle <template onenterbackward="..."> event at the end
+    var templates = currentActiveCard.getElementsByClassName('wml_template');
+    if (templates.length > 0) {
+        var oneb = templates[0].dataset.wml_onenterbackward;
+        if (!isBlank(oneb))
+        {
+            navigateToURL(oneb);
+            return;
+        }
+    }
+}
+
+
diff --git a/assets/wml/swe_wml.xsl b/assets/wml/swe_wml.xsl
new file mode 100755
index 0000000..f591824
--- /dev/null
+++ b/assets/wml/swe_wml.xsl
@@ -0,0 +1,542 @@
+<!--
+ # Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ #
+ # Redistribution and use in source and binary forms, with or without
+ # modification, are permitted provided that the following conditions are
+ # met:
+ #     * Redistributions of source code must retain the above copyright
+ #      notice, this list of conditions and the following disclaimer.
+ #    * Redistributions in binary form must reproduce the above
+ #      copyright notice, this list of conditions and the following
+ #      disclaimer in the documentation and/or other materials provided
+ #      with the distribution.
+ #    * Neither the name of The Linux Foundation nor the names of its
+ #      contributors may be used to endorse or promote products derived
+ #      from this software without specific prior written permission.
+ #
+ # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ # ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<xsl:output method="html" omit-xml-declaration="no" indent="yes"/>
+
+<xsl:variable name="wml_card">wml_card</xsl:variable>
+<xsl:variable name="wml_select">wml_select</xsl:variable>
+<xsl:variable name="wml_input">wml_input</xsl:variable>
+<xsl:variable name="wml_timer">wml_timer</xsl:variable>
+<xsl:variable name="wml_setvar">wml_setvar</xsl:variable>
+<xsl:variable name="wml_postfield">wml_postfield</xsl:variable>
+<xsl:variable name="wml_anchor_task">wml_anchor_task</xsl:variable>
+<xsl:variable name="wml_anchor_go">wml_anchor_go</xsl:variable>
+<xsl:variable name="wml_anchor_prev">wml_anchor_prev</xsl:variable>
+<xsl:variable name="select_onchange_handler">handleSelectOnchangeEvent(this)</xsl:variable>
+<xsl:variable name="wml_empty_str"></xsl:variable>
+<xsl:variable name="wml_noop_href">javascript:void();</xsl:variable>
+<xsl:variable name="wml_template">wml_template</xsl:variable>
+<xsl:variable name="wml_onevent">wml_onevent</xsl:variable>
+<xsl:variable name="wml_task_go">wml_task_go</xsl:variable>
+<xsl:variable name="wml_task_refresh">wml_task_refresh</xsl:variable>
+<xsl:variable name="wml_task_prev">wml_task_prev</xsl:variable>
+<xsl:variable name="wml_task_noop">wml_task_noop</xsl:variable>
+
+
+    <xsl:template match="/">
+        <xsl:apply-templates />
+    </xsl:template>
+
+    <xsl:template match="wml">
+        <html>
+            <head>
+                <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"></meta>
+                <link rel="stylesheet" href="file:///android_asset/wml/swe_wml.css" type="text/css"></link>
+                <script src="file:///android_asset/wml/swe_wml.js" type="text/javascript"></script>
+            </head>
+            <body class="wml_body">
+                <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+                <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+                <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+                  <xsl:apply-templates />
+            </body>
+        </html>
+    </xsl:template>
+
+    <xsl:template match="card">
+        <div>
+        <xsl:choose>
+            <xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="concat($wml_card, ' ', @class)"/></xsl:attribute></xsl:when>
+            <xsl:otherwise><xsl:attribute name="class"><xsl:value-of select="$wml_card"/></xsl:attribute></xsl:otherwise>
+        </xsl:choose>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@title"><xsl:attribute name="title"><xsl:value-of select="@title"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@onenterforward"><xsl:attribute name="data-wml_onenterforward"><xsl:value-of select="@onenterforward"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@onenterbackward"><xsl:attribute name="data-wml_onenterbackward"><xsl:value-of select="@onenterbackward"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@ontimer"><xsl:attribute name="data-wml_ontimer"><xsl:value-of select="@ontimer"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@newcontext"><xsl:attribute name="data-wml_newcontext"><xsl:value-of select="@newcontext"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@ordered"><xsl:attribute name="data-wml_ordered"><xsl:value-of select="@ordered"/></xsl:attribute></xsl:when></xsl:choose>
+        <div class="wml_card_title"><center><xsl:value-of select="@title" /></center></div>
+        <div class="wml_card_content">
+            <xsl:apply-templates />
+            <xsl:for-each select="/wml/template">
+                    <span>
+                    <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+                    <xsl:choose>
+                        <xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="concat($wml_template, ' ', @class)"/></xsl:attribute></xsl:when>
+                        <xsl:otherwise><xsl:attribute name="class"><xsl:value-of select="$wml_template"/></xsl:attribute></xsl:otherwise>
+                    </xsl:choose>
+                    <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+                    <xsl:choose><xsl:when test="@onenterforward"><xsl:attribute name="data-wml_onenterforward"><xsl:value-of select="@onenterforward"/></xsl:attribute></xsl:when></xsl:choose>
+                    <xsl:choose><xsl:when test="@onenterbackward"><xsl:attribute name="data-wml_onenterbackward"><xsl:value-of select="@onenterbackward"/></xsl:attribute></xsl:when></xsl:choose>
+                    <xsl:choose><xsl:when test="@ontimer"><xsl:attribute name="data-wml_ontimer"><xsl:value-of select="@ontimer"/></xsl:attribute></xsl:when></xsl:choose>
+                        <xsl:apply-templates />
+                    </span>
+            </xsl:for-each>
+        </div>
+        </div>
+    </xsl:template>
+
+    <xsl:template match="head|template|style|link|script" />
+
+    <xsl:template match="p">
+        <p>
+            <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:choose><xsl:when test="@align"><xsl:attribute name="align"><xsl:value-of select="@align"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:choose><xsl:when test="@mode"><xsl:attribute name="data-wml_mode"><xsl:value-of select="@mode"/></xsl:attribute></xsl:when></xsl:choose>
+                <xsl:apply-templates />
+        </p>
+    </xsl:template>
+
+    <xsl:template match="br">
+        <br>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </br>
+    </xsl:template>
+
+    <xsl:template match="pre">
+        <pre>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </pre>
+    </xsl:template>
+
+    <xsl:template match="b">
+        <b>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </b>
+    </xsl:template>
+
+    <xsl:template match="big">
+        <big>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </big>
+    </xsl:template>
+
+    <xsl:template match="em">
+        <em>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </em>
+    </xsl:template>
+
+    <xsl:template match="i">
+        <i>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </i>
+    </xsl:template>
+
+    <xsl:template match="small">
+        <small>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </small>
+    </xsl:template>
+
+    <xsl:template match="strong">
+        <strong>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </strong>
+    </xsl:template>
+
+    <xsl:template match="u">
+        <u>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </u>
+    </xsl:template>
+
+    <xsl:template match="a">
+        <a onclick="handleAOnClick(event, this)">
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@title"><xsl:attribute name="title"><xsl:value-of select="@title"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@href"><xsl:attribute name="href"><xsl:value-of select="@href"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </a>
+    </xsl:template>
+
+    <xsl:template match="img">
+        <img>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@alt"><xsl:attribute name="alt"><xsl:value-of select="@alt"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@src"><xsl:attribute name="src"><xsl:value-of select="@src"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@align"><xsl:attribute name="align"><xsl:value-of select="@align"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@height"><xsl:attribute name="height"><xsl:value-of select="@height"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@width"><xsl:attribute name="width"><xsl:value-of select="@width"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@localsrc"><xsl:attribute name="data-wml_localsrc"><xsl:value-of select="@localsrc"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@vspace"><xsl:attribute name="data-wml_vspace"><xsl:value-of select="@vspace"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@hspace"><xsl:attribute name="data-wml_hspace"><xsl:value-of select="@hspace"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </img>
+    </xsl:template>
+
+    <xsl:template match="table">
+        <table>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@title"><xsl:attribute name="title"><xsl:value-of select="@title"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@align"><xsl:attribute name="data-wml_align"><xsl:value-of select="@align"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@columns"><xsl:attribute name="data-wml_columns"><xsl:value-of select="@columns"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </table>
+    </xsl:template>
+
+    <xsl:template match="tr">
+        <tr>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@align"><xsl:attribute name="align"><xsl:value-of select="@align"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </tr>
+    </xsl:template>
+
+    <xsl:template match="td">
+        <td>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </td>
+    </xsl:template>
+
+    <xsl:template match="select">
+        <select>
+        <xsl:choose><xsl:when test="@multiple = 'true'"><xsl:attribute name="multiple"></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:attribute name="onchange"><xsl:value-of select="$select_onchange_handler"/></xsl:attribute>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose>
+            <xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="concat($wml_select, ' ', @class)"/></xsl:attribute></xsl:when>
+            <xsl:otherwise><xsl:attribute name="class"><xsl:value-of select="$wml_select"/></xsl:attribute></xsl:otherwise>
+        </xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@title"><xsl:attribute name="title"><xsl:value-of select="@title"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@name"><xsl:attribute name="name"><xsl:value-of select="@name"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@iname"><xsl:attribute name="data-wml_iname"><xsl:value-of select="@iname"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@ivalue"><xsl:attribute name="data-wml_ivalue"><xsl:value-of select="@ivalue"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </select>
+    </xsl:template>
+
+    <xsl:template match="option">
+        <option>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@title"><xsl:attribute name="title"><xsl:value-of select="@title"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@value"><xsl:attribute name="value"><xsl:value-of select="@value"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@onpick"><xsl:attribute name="data-wml_onpick"><xsl:value-of select="@onpick"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </option>
+    </xsl:template>
+
+    <xsl:template match="optgroup">
+        <optgroup>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@title"><xsl:attribute name="label"><xsl:value-of select="@title"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </optgroup>
+    </xsl:template>
+
+    <xsl:template match="postfield">
+        <input type="hidden">
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose>
+            <xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="concat($wml_postfield, ' ', @class)"/></xsl:attribute></xsl:when>
+            <xsl:otherwise><xsl:attribute name="class"><xsl:value-of select="$wml_postfield"/></xsl:attribute></xsl:otherwise>
+        </xsl:choose>
+        <xsl:choose><xsl:when test="@name"><xsl:attribute name="name"><xsl:value-of select="@name"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@value"><xsl:attribute name="value"><xsl:value-of select="@value"/></xsl:attribute></xsl:when></xsl:choose>
+        </input>
+    </xsl:template>
+
+    <xsl:template match="input">
+        <input>
+        <xsl:choose>
+            <xsl:when test="@type"><xsl:attribute name="type"><xsl:value-of select="@type"/></xsl:attribute></xsl:when>
+            <xsl:otherwise><xsl:attribute name="type"><xsl:value-of select="'text'"/></xsl:attribute></xsl:otherwise>
+        </xsl:choose>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose>
+            <xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="concat($wml_input, ' ', @class)"/></xsl:attribute></xsl:when>
+            <xsl:otherwise><xsl:attribute name="class"><xsl:value-of select="$wml_input"/></xsl:attribute></xsl:otherwise>
+        </xsl:choose>
+        <xsl:choose><xsl:when test="@name"><xsl:attribute name="name"><xsl:value-of select="@name"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@value"><xsl:attribute name="value"><xsl:value-of select="@value"/></xsl:attribute></xsl:when></xsl:choose>
+        </input>
+    </xsl:template>
+
+    <xsl:template match="timer">
+        <span>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose>
+            <xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="concat($wml_timer, ' ', @class)"/></xsl:attribute></xsl:when>
+            <xsl:otherwise><xsl:attribute name="class"><xsl:value-of select="$wml_timer"/></xsl:attribute></xsl:otherwise>
+        </xsl:choose>
+        <xsl:choose><xsl:when test="@name"><xsl:attribute name="data-wml_name"><xsl:value-of select="@name"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@value"><xsl:attribute name="data-wml_value"><xsl:value-of select="@value"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:apply-templates />
+        </span>
+    </xsl:template>
+
+    <xsl:template match="setvar">
+        <span>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose>
+            <xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="concat($wml_setvar, ' ', @class)"/></xsl:attribute></xsl:when>
+            <xsl:otherwise><xsl:attribute name="class"><xsl:value-of select="$wml_setvar"/></xsl:attribute></xsl:otherwise>
+        </xsl:choose>
+        <xsl:choose><xsl:when test="@name"><xsl:attribute name="data-wml_name"><xsl:value-of select="@name"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="@value"><xsl:attribute name="data-wml_value"><xsl:value-of select="@value"/></xsl:attribute></xsl:when></xsl:choose>
+        </span>
+    </xsl:template>
+
+    <xsl:template match="do">
+    <div>
+        <xsl:apply-templates />
+    </div>
+    </xsl:template>
+
+    <xsl:template match="do/go">
+    <form>
+        <xsl:attribute name="action"><xsl:value-of select="@href"/></xsl:attribute>
+        <xsl:choose><xsl:when test="@href"><xsl:attribute name="data-wml_href"><xsl:value-of select="@href"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose>
+                <xsl:when test="@method"><xsl:attribute name="method"><xsl:value-of select="@method"/></xsl:attribute></xsl:when>
+                <xsl:otherwise><xsl:attribute name="method"><xsl:value-of select="'get'"/></xsl:attribute></xsl:otherwise>
+        </xsl:choose>
+        <xsl:apply-templates />
+        <input type="button" onclick="executeGoTask(event, this.parentNode)">
+            <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:choose>
+                <xsl:when test="../@label"><xsl:attribute name="value"><xsl:value-of select="../@label"/></xsl:attribute></xsl:when>
+                <xsl:otherwise>
+                    <xsl:choose>
+                        <xsl:when test="../@name"><xsl:attribute name="value"><xsl:value-of select="../@name" /></xsl:attribute></xsl:when>
+                        <xsl:otherwise><xsl:attribute name="value"><xsl:value-of select="'OK'"/></xsl:attribute></xsl:otherwise>
+                    </xsl:choose>
+                </xsl:otherwise>
+            </xsl:choose>
+        </input>
+    </form>
+    </xsl:template>
+
+    <xsl:template match="do/refresh">
+    <input type="button" onclick="executeRefreshTask(event, this)">
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose>
+            <xsl:when test="../@label"><xsl:attribute name="value"><xsl:value-of select="../@label"/></xsl:attribute></xsl:when>
+            <xsl:otherwise>
+                <xsl:choose>
+                    <xsl:when test="../@name"><xsl:attribute name="value"><xsl:value-of select="../@name" /></xsl:attribute></xsl:when>
+                    <xsl:otherwise><xsl:attribute name="value"><xsl:value-of select="'Refresh'"/></xsl:attribute></xsl:otherwise>
+                </xsl:choose>
+            </xsl:otherwise>
+        </xsl:choose>
+    </input>
+    <span>
+        <xsl:apply-templates />
+    </span>
+    </xsl:template>
+
+    <xsl:template match="do/prev">
+    <input type="button" onclick="executePrevTask(event, this)">
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose>
+            <xsl:when test="../@label"><xsl:attribute name="value"><xsl:value-of select="../@label"/></xsl:attribute></xsl:when>
+            <xsl:otherwise>
+                <xsl:choose>
+                    <xsl:when test="../@name"><xsl:attribute name="value"><xsl:value-of select="../@name" /></xsl:attribute></xsl:when>
+                    <xsl:otherwise><xsl:attribute name="value"><xsl:value-of select="'Back'"/></xsl:attribute></xsl:otherwise>
+                </xsl:choose>
+            </xsl:otherwise>
+        </xsl:choose>
+    </input>
+        <xsl:apply-templates />
+    </xsl:template>
+
+    <xsl:template match="do/noop">
+    <span></span>
+    </xsl:template>
+
+    <xsl:template match="anchor">
+    <div>
+        <xsl:apply-templates />
+    </div>
+    </xsl:template>
+
+    <xsl:template match="anchor/go">
+    <form>
+        <xsl:attribute name="action"><xsl:value-of select="@href"/></xsl:attribute>
+        <xsl:choose><xsl:when test="@href"><xsl:attribute name="data-wml_href"><xsl:value-of select="@href"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose>
+                <xsl:when test="@method"><xsl:attribute name="method"><xsl:value-of select="@method"/></xsl:attribute></xsl:when>
+                <xsl:otherwise><xsl:attribute name="method"><xsl:value-of select="'get'"/></xsl:attribute></xsl:otherwise>
+        </xsl:choose>
+        <a onclick="executeGoTask(event, this.parentNode)">
+            <xsl:choose>
+                <xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="concat($wml_anchor_task, ' ', @class)"/></xsl:attribute></xsl:when>
+                <xsl:otherwise><xsl:attribute name="class"><xsl:value-of select="$wml_anchor_task"/></xsl:attribute></xsl:otherwise>
+            </xsl:choose>
+            <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:choose><xsl:when test="@href"><xsl:attribute name="href"><xsl:value-of select="@href"/></xsl:attribute></xsl:when></xsl:choose>
+            <xsl:attribute name="data-wml_task_type"><xsl:value-of select="$wml_task_go"/></xsl:attribute>
+                <xsl:apply-templates />
+        </a>
+    </form>
+    </xsl:template>
+
+    <xsl:template match="anchor/prev">
+        <xsl:apply-templates />
+    <a href="javascript:void(0);" onclick="executePrevTask(event, this)">
+        <xsl:choose>
+            <xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="concat($wml_anchor_task, ' ', @class)"/></xsl:attribute></xsl:when>
+            <xsl:otherwise><xsl:attribute name="class"><xsl:value-of select="$wml_anchor_task"/></xsl:attribute></xsl:otherwise>
+        </xsl:choose>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:attribute name="data-wml_task_type"><xsl:value-of select="$wml_task_prev"/></xsl:attribute>
+    </a>
+    </xsl:template>
+
+    <xsl:template match="anchor/refresh">
+    <a href="javascript:void(0);" onclick="executeRefreshTask(event, this)">
+        <xsl:choose>
+            <xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="concat($wml_anchor_task, ' ', @class)"/></xsl:attribute></xsl:when>
+            <xsl:otherwise><xsl:attribute name="class"><xsl:value-of select="$wml_anchor_task"/></xsl:attribute></xsl:otherwise>
+        </xsl:choose>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:attribute name="data-wml_task_type"><xsl:value-of select="$wml_task_refresh"/></xsl:attribute>
+            <xsl:apply-templates />
+    </a>
+    </xsl:template>
+
+    <xsl:template match="onevent">
+    <div>
+        <xsl:attribute name="class"><xsl:value-of select="$wml_onevent"/></xsl:attribute>
+        <xsl:apply-templates />
+    </div>
+    </xsl:template>
+
+    <xsl:template match="onevent/go">
+    <form>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose>
+            <xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="concat($wml_onevent, '_', ../@type, ' ', @class)"/></xsl:attribute></xsl:when>
+            <xsl:otherwise><xsl:attribute name="class"><xsl:value-of select="concat($wml_onevent, '_', ../@type)"/></xsl:attribute></xsl:otherwise>
+        </xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="../@type"><xsl:attribute name="data-wml_onevent_type"><xsl:value-of select="../@type"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:attribute name="data-wml_task_type"><xsl:value-of select="$wml_task_go"/></xsl:attribute>
+        <xsl:attribute name="action"><xsl:value-of select="@href"/></xsl:attribute>
+        <xsl:choose><xsl:when test="@href"><xsl:attribute name="data-wml_href"><xsl:value-of select="@href"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose>
+                <xsl:when test="@method"><xsl:attribute name="method"><xsl:value-of select="@method"/></xsl:attribute></xsl:when>
+                <xsl:otherwise><xsl:attribute name="method"><xsl:value-of select="'get'"/></xsl:attribute></xsl:otherwise>
+        </xsl:choose>
+        <xsl:apply-templates />
+    </form>
+    </xsl:template>
+
+    <xsl:template match="onevent/refresh">
+    <span>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose>
+            <xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="concat($wml_onevent, '_', ../@type, ' ', @class)"/></xsl:attribute></xsl:when>
+            <xsl:otherwise><xsl:attribute name="class"><xsl:value-of select="concat($wml_onevent, '_', ../@type)"/></xsl:attribute></xsl:otherwise>
+        </xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="../@type"><xsl:attribute name="data-wml_onevent_type"><xsl:value-of select="../@type"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:attribute name="data-wml_task_type"><xsl:value-of select="$wml_task_refresh"/></xsl:attribute>
+            <xsl:apply-templates />
+    </span>
+    </xsl:template>
+
+    <xsl:template match="onevent/prev">
+    <span>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose>
+            <xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="concat($wml_onevent, '_', ../@type, ' ', @class)"/></xsl:attribute></xsl:when>
+            <xsl:otherwise><xsl:attribute name="class"><xsl:value-of select="concat($wml_onevent, '_', ../@type)"/></xsl:attribute></xsl:otherwise>
+        </xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="../@type"><xsl:attribute name="data-wml_onevent_type"><xsl:value-of select="../@type"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:attribute name="data-wml_task_type"><xsl:value-of select="$wml_task_prev"/></xsl:attribute>
+            <xsl:apply-templates />
+    </span>
+    </xsl:template>
+
+    <xsl:template match="onevent/noop">
+    <span>
+        <xsl:choose><xsl:when test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose>
+            <xsl:when test="@class"><xsl:attribute name="class"><xsl:value-of select="concat($wml_onevent, '_', ../@type, ' ', @class)"/></xsl:attribute></xsl:when>
+            <xsl:otherwise><xsl:attribute name="class"><xsl:value-of select="concat($wml_onevent, '_', ../@type)"/></xsl:attribute></xsl:otherwise>
+        </xsl:choose>
+        <xsl:choose><xsl:when test="@lang"><xsl:attribute name="lang"><xsl:value-of select="@lang"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:choose><xsl:when test="../@type"><xsl:attribute name="data-wml_onevent_type"><xsl:value-of select="../@type"/></xsl:attribute></xsl:when></xsl:choose>
+        <xsl:attribute name="data-wml_task_type"><xsl:value-of select="$wml_task_noop"/></xsl:attribute>
+            <xsl:apply-templates />
+    </span>
+    </xsl:template>
+
+</xsl:stylesheet>
diff --git a/swe_android_browser.gypi b/swe_android_browser.gypi
index 6873fc3..1d70810 100644
--- a/swe_android_browser.gypi
+++ b/swe_android_browser.gypi
@@ -15,6 +15,7 @@
         'app_manifest_version_code': '<!(../swe/browser/tools/generate_about.sh --quiet --code)',
         'java_in_dir': '.',
         'resource_dir': '../../swe/browser/res',
+        'assets_dir': '../../swe/browser/assets',
         'native_lib_target': 'libswewebviewchromium',
         'additional_input_paths': ['<(PRODUCT_DIR)/android_webview_apk/assets/webviewchromium.pak'],
         'additional_native_libs': ['<@(libnetxt_native_libs)']
@@ -26,6 +27,14 @@
                 '<(PRODUCT_DIR)/android_webview_apk/assets/webviewchromium.pak'
               ],
         },
+        {
+              'destination': '<(PRODUCT_DIR)/swe_android_browser_apk/assets/wml',
+              'files': [
+                '<(assets_dir)/wml/swe_wml.xsl',
+                '<(assets_dir)/wml/swe_wml.js',
+                '<(assets_dir)/wml/swe_wml.css',
+              ],
+        },
       ],
       'includes': [ '../../build/java_apk.gypi' ],
     },