You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by js...@apache.org on 2013/08/26 05:04:34 UTC

svn commit: r1517415 [3/3] - in /tuscany/sca-cpp/trunk: ./ modules/http/ modules/js/ modules/js/htdocs/ patches/ ubuntu/

Modified: tuscany/sca-cpp/trunk/modules/js/htdocs/ui.js
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/htdocs/ui.js?rev=1517415&r1=1517414&r2=1517415&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/htdocs/ui.js (original)
+++ tuscany/sca-cpp/trunk/modules/js/htdocs/ui.js Mon Aug 26 03:04:34 2013
@@ -26,37 +26,8 @@ var ui = {};
 /**
  * Return a child element of a node with the given id.
  */
-ui.elementByID = function(node, id) {
-    if (node.skipNode == true)
-        return null;
-    if (node == document)
-        return document.getElementById(id);
-    for (var i in node.childNodes) {
-        var child = node.childNodes[i];
-        if (isNull(child))
-            continue;
-        if (child.id == id)
-            return child;
-        var gchild = ui.elementByID(child, id);
-        if (gchild != null)
-            return gchild;
-    }
-    return null;
-};
-
-/**
- * Remove ids in a tree of elements.
- */
-ui.removeElementIDs = function(node) {
-    if (!isNull(node.id))
-        node.id = null;
-    for (var i in node.childNodes) {
-        var child = node.childNodes[i];
-        if (isNull(child))
-            continue;
-        ui.removeElementIDs(child);
-    }
-    return true;
+ui.elementByID = function(id) {
+    return document.getElementById(id);
 };
 
 /**
@@ -65,16 +36,25 @@ ui.removeElementIDs = function(node) {
 function $(id) {
     if (id == document)
         return document;
-    return memo(document, '$' + id, function() {
-        return ui.elementByID($(document), id);
-    });
+    return document.getElementById(id);
 }
 
 /**
- * Un-memoize elements previously found by id.
+ * Remove ids from a tree of elements.
  */
-ui.unmemo$ = function(prefix) {
-    return prefix? unmemo(document, '$' + prefix) : unmemo(document);
+ui.removeElementIDs = function(node) {
+    function cleanIDs(node) {
+        for(var i = 0; i < node.childNodes.length; i++) {
+            var c = node.childNodes[i];
+            if(c.nodeType == 1) {
+                if (c.id != null)
+                    c.id = null;
+                cleanIDs(c);
+            }
+        }
+        return true;
+    }
+    return cleanIDs(node);
 };
 
 /**
@@ -105,7 +85,7 @@ ui.fragment = function(url) {
 /**
  * Return the path and parameters of a URL.
  */
-ui.pathandparams = function(url) {
+ui.pathAndParams = function(url) {
     var u = '' + url;
     var ds = u.indexOf('//');
     var u2 = ds > 0? u.substring(ds + 2) : u;
@@ -117,7 +97,7 @@ ui.pathandparams = function(url) {
  * Return a dictionary of query parameters in a URL.
  */
 ui.queryParams = function(url) {
-    var qp = new Array();
+    var qp = [];
     var qs = ui.query(url).split('&');
     for (var i = 0; i < qs.length; i++) {
         var e = qs[i].indexOf('=');
@@ -131,7 +111,7 @@ ui.queryParams = function(url) {
  * Return a dictionary of fragment parameters in a URL.
  */
 ui.fragmentParams = function(url) {
-    var qp = new Array();
+    var qp = [];
     var qs = ui.fragment(url).split('&');
     for (var i = 0; i < qs.length; i++) {
         var e = qs[i].indexOf('=');
@@ -142,23 +122,79 @@ ui.fragmentParams = function(url) {
 };
 
 /**
+ * Get a style property a DOM element.
+ */
+ui.getStyle = function(e, name) {
+    return e.style.getPropertyValue(name);
+};
+
+/**
+ * Set a style property of a DOM element.
+ */
+ui.setStyle = function(e, name, v, async) {
+    if (e.style.getPropertyValue(name) == v)
+        return false;
+    if (!async)
+        return e.style.setProperty(name, v, null);
+    ui.render(function() {
+        return e.style.setProperty(name, v, null);
+    });
+    return true;
+};
+
+/**
+ * Remove a style property from a DOM element.
+ */
+ui.removeStyle = function(e, name, async) {
+    if (!async)
+        return e.style.removeProperty(name);
+    ui.render(function() {
+        return e.style.removeProperty(name);
+    });
+    return true;
+};
+
+/**
+ * Set the CSS class of a DOM element.
+ */
+ui.getClass = function(e) {
+    return e.className;
+};
+
+/**
+ * Set the CSS class of a DOM element.
+ */
+ui.setClass = function(e, v, async) {
+    if (e.className == v)
+        return false;
+    if (!async) {
+        e.className = v;
+        return true;
+    }
+    ui.render(function() {
+        e.className = v;
+    });
+    return true;
+};
+
+/**
  * Convert a base64-encoded PNG image to a data URL.
  */
-ui.b64png = function(b64) {
+ui.b64PNG = function(b64) {
     return 'data:image/png;base64,' + b64.trim();
 };
 
 /**
  * Convert a base64-encoded JPEG image to a data URL.
  */
-ui.b64jpeg = function(b64) {
+ui.b64JPEG = function(b64) {
     return 'data:image/jpeg;base64,' + b64.trim();
 };
 
 /**
  * Convert a data URL to a base64-encoded image.
  */
-ui.imgb64 = function(img) {
+ui.imgB64 = function(img) {
     if (img.startsWith('data:'))
         return img.split(',')[1]
     return '';
@@ -198,36 +234,36 @@ ui.declareScript = function(s) {
  * Return the scripts elements under a given element.
  */
 ui.innerScripts = function(e) {
-    return map(function(s) { return s.text; },  nodeList(e.getElementsByTagName('script')));
+    return nodeList(e.getElementsByTagName('script'));
 };
 
 /**
  * Evaluate a script.
  */
 ui.evalScript = function(s) {
-    return eval('(function evalscript() { try { \n' + s + '\n} catch(e) { debug(e.stack); throw e; }})();');
+    return eval('(function evalscript() {\n' + s + '\n})();');
 };
 
 /**
  * Include a script.
  */
 ui.includeScript = function(s) {
-    //debug('include', s);
-    return eval('try { \n' + s + '\n} catch(e) { debug(e.stack); throw e; }');
+    debug('ui.include', s);
+    return eval(s);
 };
 
 /**
  * Return true if the client is a mobile device.
  */
-ui.mobiledetected = false;
+ui.mobileDetected = false;
 ui.mobile = false;
 ui.isMobile = function() {
-    if (ui.mobiledetected)
+    if (ui.mobileDetected)
         return ui.mobile;
     var ua = navigator.userAgent;
-    if (ua.match(/iPhone/i) || ua.match(/iPad/i) || ua.match(/iPod/i) || ua.match(/Android/i) || ua.match(/Blackberry/i) || ua.match(/WebOs/i))
+    if (ua.match(/iPhone/i) || ua.match(/iPad/i) || ua.match(/iPod/i) || ua.match(/Android/i) || ua.match(/Blackberry/i) || ua.match(/WebOs/i) || ua.match(/Mobile.*Firefox/i))
         ui.mobile = true;
-    ui.mobiledetected = true;
+    ui.mobileDetected = true;
     return ui.mobile;
 };
 
@@ -246,17 +282,17 @@ ui.webkitVersion = function() {
 };
 
 /**
- * Return the Safari version.
+ * Return true if the client is Android based.
  */
-ui.browserVersion = function() {
-    return Number(navigator.userAgent.replace(/.*Version\/(\d+\.\d+).*/, '$1'));
+ui.isAndroid = function() {
+    return navigator.userAgent.match(/Android/i);
 };
 
 /**
- * Return true if the client is Android based.
+ * Return the Android version.
  */
-ui.isAndroid = function() {
-    return navigator.userAgent.match(/Android/i);
+ui.androidVersion = function() {
+    return Number(navigator.userAgent.replace(/.*Version\/(\d+\.\d+).*/, '$1'));
 };
 
 /**
@@ -281,6 +317,13 @@ ui.isSafari = function() {
 };
 
 /**
+ * Return the Safari version.
+ */
+ui.safariVersion = function() {
+    return Number(navigator.userAgent.replace(/.*Version\/(\d+\.\d+).*/, '$1'));
+};
+
+/**
  * Return true if the client is Chrome.
  */
 ui.isChrome = function() {
@@ -288,6 +331,13 @@ ui.isChrome = function() {
 };
 
 /**
+ * Return the Chrome version.
+ */
+ui.chromeVersion = function() {
+    return Number(navigator.userAgent.replace(/.*Chrome\/(\d+\.\d+).*/, '$1'));
+};
+
+/**
  * Return true if the client is Internet Explorer.
  */
 ui.isMSIE = function() {
@@ -302,25 +352,55 @@ ui.msieVersion = function() {
 };
 
 /**
+ * Run a UI animation.
+ */
+ui.animationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame ||
+    function(f) {
+        if (isNull(f.interval)) {
+            // First call, setup the interval
+            f.interval = window.setInterval(function animation() {
+                f.clearInterval = true;
+
+                // Call the animation function
+                f();
+
+                // If the animation function didn't call ui.animation again to
+                // request another animation frame, clear the interval
+                if (f.clearInterval) {
+                    f.clearInterval = false;
+                    window.clearInterval(f.interval);
+                    f.interval = null;
+                }
+            }, 16);
+        } else {
+            // Called to request another animation frame, do not clear the
+            // interval
+            f.clearInterval = false;
+        }
+    };
+
+ui.animation = function(f) {
+    return ui.animationFrame.call(window, f);
+};
+
+/**
  * Run a UI rendering function asynchronously.
  */
-ui.async = function(f, t) {
-    window.setTimeout(function() {
-        return f();
-    }, isNull(t)? 0 : t);
-    return true;
+ui.render = function(f) {
+    return ui.animation(f);
 };
 
 /**
  * Delay the execution of a function.
  */
-ui.delayed = {}
-ui.delay = function(f, t) {
-    var id = window.setTimeout(function() {
-        delete ui.delayed[id];
+ui.unimportant = {}
+ui.delay = function(f, t, unimportant) {
+    var id = window.setTimeout(function delayed() {
+        delete ui.unimportant[id];
         return f();
     }, isNull(t)? 0 : t);
-    ui.delayed[id] = id;
+    if (unimportant)
+        ui.unimportant[id] = id;
     return id;
 };
 
@@ -328,56 +408,253 @@ ui.delay = function(f, t) {
  * Cancel the execution of a delayed function.
  */
 ui.cancelDelay = function(id) {
-    delete ui.delayed[id];
+    delete ui.unimportant[id];
     return window.clearTimeout(id);
 };
 
 /**
- * Run a UI animation.
+ * Convert a CSS position to a numeric position.
  */
-ui.animationFrame = null;
-ui.animation = function(f) {
-    if (isNull(ui.animationFrame))
-        // Use requestAnimationFrame when available, fallback to setInterval
-        ui.animationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame ||
-            window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
-            function(f) {
-                if (!('interval' in f) || isNull(f.interval)) {
-                    // First call, setup the interval
-                    f.interval = window.setInterval(function animation() {
-                        f.clearInterval = true;
-                        try {
-                            f();
-                        } catch(ex) {}
-                        // If the animation function didn't call ui.animation again to
-                        // request another animation frame, clear the interval
-                        if (f.clearInterval) {
-                            f.clearInterval = false;
-                            window.clearInterval(f.interval);
-                            f.interval = null;
-                        }
-                    }, 16);
-                } else {
-                    // Called to request another animation frame, do not clear the
-                    // interval
-                    f.clearInterval = false;
-                }
-            };
-    return ui.animationFrame.call(window, f);
+ui.npos = function(p) {
+    return p == null || p == ''? 0 : Number(p.substr(0, p.length - 2));
 };
 
 /**
- * Convert a CSS position to a numeric position.
+ * Convert a numeric position to a CSS pixel position.
  */
-ui.numpos = function(p) {
-    return p == ''? 0 : Number(p.substr(0, p.length - 2));
+ui.pxpos = function(p) {
+    return p + 'px';
 };
 
 /**
- * Convert a numeric position to a CSS pixel position.
+ * Show a status message.
  */
-ui.pixpos = function(p) {
-    return p + 'px';
+ui.statusElement = undefined;
+
+ui.initStatus = function() {
+    ui.statusElement = $('status');
+    if (isNull(ui.statusElement))
+        return;
+    ui.setClass(ui.statusElement, ui.isMobile()? 'status3dm' : 'status3d');
+    ui.setStyle(ui.statusElement, 'display', 'none');
+    
+    function divtransitionend(e) {
+        ui.setClass(e.target, ui.isMobile()? 'status3dm' : 'status3d');
+        ui.setStyle(e.target, 'display', 'none');
+        e.target.error = false;
+    }
+    ui.statusElement.addEventListener('webkitTransitionEnd', divtransitionend, false);
+    ui.statusElement.addEventListener('transitionend', divtransitionend, false);
+    return true;
+};
+
+ui.status = function(s, c) {
+    debug('ui.status', s);
+    if(isNull(ui.statusElement) || ui.statusElement.error)
+        return s;
+    ui.statusElement.innerHTML = '<span class="' + (c? c : 'okstatus') + '">' + s + '</span>';
+    ui.setClass(ui.statusElement, ui.isMobile()? 'status3dm' : 'status3d');
+    ui.setStyle(ui.statusElement, 'display', 'block');
+    ui.statusElement.error = c == 'errorstatus';
+    if(ui.statusElement.delay)
+        ui.cancelDelay(ui.statusElement.delay);
+    ui.statusElement.delay = ui.delay(function hidestatus() {
+        ui.setClass(ui.statusElement, ui.isMobile()? 'statusout3dm' : 'statusout3d');
+        ui.statusElement.error = false;
+    }, c == 'errorstatus'? 8000 : 3000);
+    return s;
+};
+
+/**
+ * Show an error message.
+ */
+ui.error = function(s) {
+    debug('ui.error', s);
+    return ui.status(s, 'errorstatus');
+};
+
+/**
+ * Show the online/offline status.
+ */
+ui.onlineStatus = function() {
+    return navigator.onLine? true : errorstatus('Offline');
+};
+
+/**
+ * Show the working/ready indicator.
+ */
+ui.workingElement = undefined;
+ui.initWorking = function() {
+    ui.workingElement = $('working');
+};
+
+ui.working = function() {
+    debug('ui.working');
+    if (isNull(ui.workingElement))
+        return false;
+    return ui.setStyle(ui.workingElement, 'display', 'block');
+};
+
+ui.ready = function() {
+    debug('ui.ready');
+    if (isNull(ui.workingElement))
+        return false;
+    return ui.setStyle(ui.workingElement, 'display', 'none');
+};
+
+/**
+ * Get and cache a resource.
+ */
+ui.appcache = {};
+ui.appcache.get = function(uri, mode) {
+    debug('ui.appcache.get', uri, mode);
+
+    // Get resource from local storage first
+    var h = uri.indexOf('#');
+    var u = h == -1? uri : uri.substring(0, h);
+    if(mode != 'remote') {
+        var item = lstorage.getItem('ui.r.' + u);
+        if(item != null && item != '')
+            return item;
+        if(mode == 'local')
+            return undefined;
+    }
+
+    // Get resource from network
+    var http = new XMLHttpRequest();
+    http.open("GET", mode == 'remote'? (u + '?t=' + new Date().getTime() + '&r=' + Math.random()) : u, false);
+    http.setRequestHeader('Accept', '*/*');
+    http.setRequestHeader('X-Cache-Control', 'no-cache');
+    http.send(null);
+    if(http.status == 200) {
+        var ct = http.getResponseHeader("Content-Type");
+        if(http.responseText == '' || ct == null || ct == '') {
+            error('http error', u, 'No-Content');
+            return undefined;
+        }
+        lstorage.setItem('ui.r.' + u, http.responseText);
+        return http.responseText;
+    }
+    error('http error', u, http.status, http.statusText);
+
+    // Redirect to login page
+    if(http.status == 403 && window.top.location.href.pathname != '/logout/dologout/') {
+        if(window.onloginredirect)
+            window.onloginredirect(new Error('403 ' + http.statusText));
+    }
+    return undefined;
+};
+
+/**
+ * Remove a resource from the cache.
+ */
+ui.appcache.remove = function(uri) {
+    debug('ui.appcache.remove', uri);
+    var h = uri.indexOf('#');
+    var u = h == -1? uri : uri.substring(0, h);
+    return lstorage.removeItem(u);
+};
+
+/**
+ * Default app cache handling behavior.
+ */
+ui.onappcache = function(manifest, resources) {
+
+    if(ui.isMobile() && !ui.isFirefox()) {
+        // On mobile devices, trigger usage of an application cache manifest
+        // Except on mobile Firefox which fails to send cookies with cache manifest requests
+        window.onappcachechecking = function(e) {
+            debug('appcache checking', e);
+            ui.working();
+        };
+        window.onappcacheerror = function(e) {
+            debug('appcache error', e);
+            ui.onlineStatus();
+            ui.ready();
+            return false;
+        };
+        window.onappcachenoupdate = function(e) {
+            debug('appcache noupdate', e);
+            ui.ready();
+        };
+        window.onappcachedownloading = function(e) {
+            debug('appcache downloading', e);
+            ui.working();
+            ui.status('Updating');
+        };
+        window.onappcacheprogress = function(e) {
+            debug('appcache progress', e);
+            ui.working();
+            ui.status('Updating');
+        };
+        window.onappcacheupdateready = function(e) {
+            debug('appcache updateready', e);
+
+            // Update offline resources in local storage and reload the page
+            ui.status('Updating');
+            applicationCache.swapCache();
+            ui.delay(function swapappcache() {
+                debug('appcache swapped', e);
+                map(function(res) {
+                    ui.appcache.remove(car(res));
+                    ui.appcache.get(car(res), 'remote');
+                }, resources);
+                ui.status('Installed');
+                ui.ready();
+
+                debug('reloading');
+                window.location.reload();
+            });
+        };
+        window.onappcachecached = function(e) {
+            debug('appcache cached', e);
+
+            // Install offline resources in local storage
+            ui.status('Installing');
+            ui.delay(function installoffline() {
+                map(function(res) {
+                    ui.appcache.remove(car(res));
+                    ui.appcache.get(car(res), 'remote');
+                }, resources);
+                ui.status('Installed');
+                ui.ready();
+            });
+        };
+
+        window.onloadappcache = function() {
+            debug('appcache iframe loaded');
+        };
+
+        var installer = $('installer');
+        installer.innerHTML = '<iframe src="' + manifest + '/" class="installer"></iframe>';
+
+    } else {
+        // On non-mobile devices, check for cache-manifest changes ourselves.
+        ui.working();
+        var lcmf = ui.appcache.get(manifest + '/cache-manifest.cmf', 'local');
+        var rcmf = ui.appcache.get(manifest + '/cache-manifest.cmf', 'remote');
+        if(lcmf == rcmf) {
+            ui.ready();
+            return true;
+        }
+
+        debug('cache-manifest changed, reloading');
+        ui.status(isNull(lcmf)? 'Installing' : 'Updating');
+        ui.delay(function reloadapp() {
+            map(function(res) {
+                ui.appcache.remove(car(res));
+                ui.appcache.get(car(res), 'remote');
+            }, resources);
+            ui.ready();
+            if(!isNull(lcmf)) {
+                ui.status('Installed');
+                ui.ready();
+
+                debug('reloading');
+                window.location.reload();
+            }
+        });
+    }
 };
 
 /**
@@ -385,28 +662,49 @@ ui.pixpos = function(p) {
  */
 ui.filler = null;
 ui.onload = function() {
+    debug('ui.onload');
+
+    // Initialize status and working elements
+    ui.initStatus();
+    ui.initWorking();
+
+    // Set orientation change handler
+    document.body.onorientationchange = function(e) {
+        return ui.onorientationchange(e);
+    };
+
+    // Handle network offline/online events.
+    window.addEventListener('offline', function(e) {
+        debug('going offline');
+        ui.status('Offline');
+    }, false);
+    window.addEventListener('online', function(e) {
+        debug('going online');
+        ui.status('Online');
+    }, false);
 
     // Add a filler div to make sure we can scroll
     if (ui.isMobile()) {
         ui.filler = document.createElement('div');
         ui.filler.id = 'filler';
-        ui.filler.className = 'filler';
-        ui.filler.style.height = ui.pixpos(window.orientation == 0? screen.height : screen.width * 2);
+        ui.setClass(ui.filler, 'filler');
+        ui.setStyle(ui.filler, 'height', ui.pxpos(window.orientation == 0? Math.floor(window.innerHeight * 1.5) : Math.floor(window.innerHeight * 1.5)));
         document.body.appendChild(ui.filler);
     } else {
         // Style scroll bars
-        var h = document.getElementsByTagName('html');
-        if (!isNull(h))
-            h[0].className = h[0].className? h[0].classname + ' flatscrollbars' : 'flatscrollbars';
+        var h = nodeList(document.getElementsByTagName('html'));
+        if (!isNull(h)) {
+            ui.setClass(car(h), car(h).className? car(h).classname + ' flatscrollbars' : 'flatscrollbars');
+        }
     }
 
     // Scroll to hide the address bar
-    document.body.style.display = 'block';
-    window.scrollTo(0, 0);
+    ui.setStyle(document.body, 'display', 'block');
+    document.body.scrollTop = 0;
 
     // Set unload handler
     window.onunload = function() {
-        window.scrollTo(0, 0);
+        document.body.scrollTop = 0;
         return true;
     };
 
@@ -417,13 +715,15 @@ ui.onload = function() {
  * Default orientation change behavior.
  */
 ui.onorientationchange = function(e) {
+    debug('ui.onorientationchange');
 
     // Adjust filler height
     if (!isNull(ui.filler))
-        ui.filler.style.height = ui.pixpos(window.orientation == 0? screen.height : screen.width);
+        ui.setStyle(ui.filler, 'height', ui.pxpos(window.orientation == 0? Math.floor(window.innerHeight * 1.5) : Math.floor(window.innerHeight * 1.5)));
 
-    // Scroll to hide the address bar
-    window.scrollTo(0, 0);
+    // Scroll to refresh the page
+    document.body.scrollTop = document.body.scrollTop + 1;
+    document.body.scrollTop = document.body.scrollTop - 1;
     return true;
 };
 
@@ -431,22 +731,52 @@ ui.onorientationchange = function(e) {
  * Navigate to a new document.
  */
 ui.navigate = function(url, win) {
-    //debug('navigate', url, win);
+    debug('ui.navigate', url, win);
+    if (url == '' || url == '#')
+        return false;
+
+    function cleanup() {
+        // Cleanup window event handlers
+        window.onclick = null;
+        if (!ui.isMobile()) {
+            window.onmousedown = null;
+            window.onmouseup = null;
+            window.onmousemove = null;
+        } else {
+            window.ontouchstart = null;
+            window.ontouchend = null;
+            window.ontouchmove = null;
+        }
+
+        // Cancel any cancelable HTTP requests
+        if (typeof HTTPBindingClient != 'undefined')
+            HTTPBindingClient.cancelRequests();
+
+        // Automatically cancel unimportant timers
+        for (var d in ui.unimportant)
+            ui.cancelDelay(d);
+        return true;
+    }
 
     // Open a new window
     if (win == '_blank') {
+        debug('window.open', url, win);
         window.top.open(url, win);
         return false;
     }
 
     // Open a new document in the current window
     if (win == '_self') {
+        cleanup();
+        debug('window.open', url, win);
         window.top.open(url, win);
         return false;
     }
 
     // Reload the current window
     if (win == '_reload') {
+        cleanup();
+        debug('window.reload', url);
         window.top.location = url;
         window.top.location.reload();
         return false;
@@ -454,36 +784,18 @@ ui.navigate = function(url, win) {
 
     // Let the current top window handle the navigation
     if (win == '_view') {
-        if (!window.top.onnavigate)
-            return window.top.open(url, '_self');
+        cleanup();
 
-        // Cleanup window event handlers
-        window.onclick = null;
-        if (!ui.isMobile()) {
-            window.onmousedown = null;
-            window.onmouseup = null;
-            window.onmousemove = null;
-        } else {
-            window.ontouchstart = null;
-            window.ontouchend = null;
-            window.ontouchmove = null;
+        if (!window.top.onnavigate) {
+            debug('window.open', url, '_self');
+            window.top.open(url, '_self');
+            return false;
         }
-
-        // Cancel any cancelable HTTP requests
-        HTTPBindingClient.cancelRequests();
-
-        // Cleanup memoized element lookups
-        ui.unmemo$();
-
-        // Cancel any timers
-        for (d in ui.delayed)
-            ui.cancelDelay(d);
-
-        // Navigate
         window.top.onnavigate(url);
         return false;
     }
 
+    debug('window.open', url, win);
     window.top.open(url, win);
     return false;
 }
@@ -492,7 +804,7 @@ ui.navigate = function(url, win) {
  * Bind a click handler to a widget.
  */
 ui.ontouchstart = function(widget, e) {
-    //debug('ontouchstart');
+    debug('ui.ontouchstart', widget.id);
     widget.down = true;
     widget.moved = false;
     var t = e.touches[0];
@@ -514,10 +826,11 @@ ui.ontouchmove = function(widget, e) {
 };
 
 ui.ontouchend = function(widget, e) {
-    //debug('ontouchend');
+    debug('ui.ontouchend', widget.id);
     widget.down = false;
     if (!widget.moved) {
         e.preventDefault();
+        debug('ui.fastonclick', widget.id);
         return widget.onclick(e);
     }
 };
@@ -535,7 +848,7 @@ ui.onclick = function(widget, handler) {
         };
     }
     widget.onclick = function(e) {
-        //debug('onclick');
+        debug('ui.onclick', widget.id);
         return handler(e);
     };
     return widget;
@@ -544,61 +857,131 @@ ui.onclick = function(widget, handler) {
 /**
  * Build a portable <a href> tag.
  */
-ui.href = function(id, loc, target, html) {
+ui.href = function(id, loc, target, clazz, html) {
     if (target == '_blank')
-        return '<a id="' + id + '" href="' + loc + '" target="_blank">' + html + '</a>';
-    return '<a id="' + id + '" href="' + loc + '" ' + (ui.isMobile()? 'ontouchstart="return ui.ontouchstart(this, event);" ontouchmove="return ui.ontouchmove(this, event);" ontouchend="return ui.ontouchend(this, event);" ' : '') + 'onclick="return ui.navigate(\'' + loc + '\', \'' + target + '\');">' + html + '</a>';
+        return '<a href="' + loc + '" target="_blank"><span id="' + id + '" class="' + clazz + '">' + html + '</span></a>';
+    return '<a href="' + loc + '" ' +
+        (ui.isMobile()? 'ontouchstart="return ui.ontouchstart(this, event);" ontouchmove="return ui.ontouchmove(this, event);" ontouchend="return ui.ontouchend(this, event);" ' : '') +
+        'onclick="return ui.navigate(\'' + loc + '\', \'' + target + '\');"><span id="' + id + '" class="' + clazz + '">' + html + '</span></a>';
+};
+
+/**
+ * Update a <a href> tag.
+ */
+ui.updateHref = function(item, loc, target) {
+    if (!isNull(loc) && !isNull(target)) {
+        var link = item.parentNode;
+        if (target == '_blank') {
+            link.href = loc;
+            link.target = '_blank';
+        } else {
+            link.href = loc;
+            link.setAttribute('onclick', 'return ui.navigate(\'' + loc + '\', \'' + target + '\');');
+        }
+    }
+    return item;
 };
 
 /**
  * Build a menu bar.
  */ 
-ui.menu = function(id, name, href, target, hilight) {
+ui.menuItem = function(id, name, href, target, hilight) {
     function Menu() {
         this.content = function() {
             if (hilight == true)
-                return ui.href(id, href, target, '<span class="tbarsmenu">' + name + '</span>');
+                return ui.href(id, href, target, 'tbarsmenu', name);
             else if (hilight == false)
-                return ui.href(id, href, target, '<span class="tbaramenu">' + name + '</span>');
+                return ui.href(id, href, target, 'tbaramenu', name);
             else
-                return ui.href(id, href, target, '<span class="' + hilight + '">' + name + '</span>');
+                return ui.href(id, href, target, hilight, name);
         };
     }
     return new Menu();
 };
 
-ui.menufunc = function(id, name, fun, hilight) {
+ui.textItem = function(id, name, hilight) {
+    function Item() {
+        this.content = function() {
+            return name;
+        };
+    }
+    return new Item();
+};
+
+ui.menuFunc = function(id, name, fun, hilight) {
     function Menu() {
         this.content = function() {
-            function href(id, fun, html) {
-                return '<a id="' + id + '" href="/" ' + (ui.isMobile()? 'ontouchstart="return ui.ontouchstart(this, event);" ontouchmove="return ui.ontouchmove(this, event);" ontouchend="return ui.ontouchend(this, event);" ' : '') + 'onclick="' + fun + '">' + html + '</a>';
+            function href(id, fun, clazz, html) {
+                return '<a href="/" ' +
+                    (ui.isMobile()? 'ontouchstart="return ui.ontouchstart(this, event);" ontouchmove="return ui.ontouchmove(this, event);" ontouchend="return ui.ontouchend(this, event);" ' : '') +
+                    'onclick="' + fun + '"><span id="' + id + '" class="' + clazz + '">' + html + '</span></a>';
             }
 
             if (hilight == true)
-                return href(id, fun, '<span class="tbarsmenu">' + name + '</span>');
+                return href(id, fun, 'tbarsmenu', name);
             else if (hilight == false)
-                return href(id, fun, '<span class="tbaramenu">' + name + '</span>');
+                return href(id, fun, 'tbaramenu', name);
             else
-                return href(id, fun, '<span class="' + hilight + '">' + name + '</span>');
+                return href(id, fun, hilight, name);
         };
     }
     return new Menu();
 };
 
-ui.menubar = function(left, right) {
-    var bar = '';
-    for (i in left)
-        bar = bar + '<span class="tbarleft">' + left[i].content() + '</span>';
-    for (i in right)
-        bar = bar + '<span class="tbarright">' + right[i].content() + '</span>';
-    return bar;
+ui.menuBar = function(left, center, right) {
+    return '<span class="tbartitle">' +
+        reduce(function(bar, item) {
+            return bar + '<span class="tbarcenter">' + item.content() + '</span>';
+        }, '', center) +
+        '</span><span class="tbaritems">' +
+        reduce(function(bar, item) {
+            return bar + '<span class="tbarleft">' + item.content() + '</span>';
+        }, '', left) +
+        reduce(function(bar, item) {
+            return bar + '<span class="tbarright">' + item.content() + '</span>';
+        }, '', right) +
+        '</span>';
+};
+
+ui.cmenuBar = function(items) {
+    return reduce(function(bar, item) {
+            return bar + '<span class="tbarcenter">' + item.content() + '</span>';
+        }, '', items);
 };
  
 /**
- * Convert a list of elements to an HTML table.
+ * Update a menu item.
  */
-ui.datatable = function(l) {
+ui.updateMenuItem = function(item, name, href, target, hilight) {
+    if (!isNull(name)) {
+        if (item.innerHTML != name)
+            item.innerHTML = name;
+    }
+    if (!isNull(hilight)) {
+        if (hilight == true)
+            ui.setClass(item, 'tbarsmenu');
+        else if (hilight == false)
+            ui.setClass(item, 'tbaramenu');
+        else
+            ui.setClass(item, hilight);
+    }
+    if (!isNull(href) && !isNull(target)) {
+        var link = item.parentNode;
+        if (target == '_blank') {
+            link.href = href;
+            link.target = '_blank';
+        } else {
+            link.href = href;
+            link.setAttribute('onclick', 'return ui.navigate(\'' + href + '\', \'' + target + '\');');
+        }
+    }
+    return item;
+};
 
+/**
+ * Convert a list of elements to an HTML table.
+ */
+ui.dataTable = function(l) {
     function indent(i) {
         if (i == 0)
             return '';
@@ -621,30 +1004,23 @@ ui.datatable = function(l) {
         // Generate table row for a simple element value
         if (elementHasValue(e)) {
             var v = elementValue(e);
-            if (!isList(v)) {
-                return '<tr><td class="datatdl">' + indent(i) + elementName(e).slice(1) + '</td>' +
-                    '<td class="datatdr tdw">' + (v != null? v : '') + '</td></tr>' +
-                    rows(cdr(l), i);
-            }
-
+            if (!isList(v))
+                return '<tr><td class="datatdl">' + indent(i) + elementName(e).substring(1) + '</td>' +
+                    '<td class="datatdr tdw">' + (v != null? v : '') + '</td></tr>' + rows(cdr(l), i);
             return rows(expandElementValues(elementName(e), v), i) + rows(cdr(l), i);
         }
 
         // Generate table row for an element with children
-        return '<tr><td class="datatdl">' + indent(i) + elementName(e).slice(1) + '</td>' +
-            '<td class="datatdr tdw">' + '</td></tr>' +
-            rows(elementChildren(e), i + 1) +
-            rows(cdr(l), i);
+        return '<tr><td class="datatdl">' + indent(i) + elementName(e).substring(1) + '</td>' +
+            '<td class="datatdr tdw">' + '</td></tr>' + rows(elementChildren(e), i + 1) + rows(cdr(l), i);
     }
-
     return '<table class="datatable ' + (window.name == 'dataFrame'? ' databg' : '') + '" style="width: 100%;">' + rows(l, 0) + '</table>';
 };
 
 /**
  * Convert a list of elements to an HTML single column table.
  */
-ui.datalist = function(l) {
-
+ui.dataList = function(l) {
     function rows(l, i) {
         if (isNull(l))
             return '';
@@ -661,25 +1037,21 @@ ui.datalist = function(l) {
         // Generate table row for a simple element value
         if (elementHasValue(e)) {
             var v = elementValue(e);
-            if (!isList(v)) {
-                return '<tr><td class="datatd tdw">' + (v != null? v : '') + '</td></tr>' +
-                    rows(cdr(l), i);
-            }
-
+            if (!isList(v))
+                return '<tr><td class="datatd tdw">' + (v != null? v : '') + '</td></tr>' + rows(cdr(l), i);
             return rows(expandElementValues(elementName(e), v), i) + rows(cdr(l), i);
         }
 
         // Generate rows for an element's children
         return rows(elementChildren(e), i + 1) + rows(cdr(l), i);
     }
-
     return '<table class="datatable ' + (window.name == 'dataFrame'? ' databg' : '') + '" style="width: 100%;">' + rows(l, 0) + '</table>';
 };
 
 /**
  * Read a file and convert it to a data url.
  */
-ui.readfile = function(file, onerror, onprogress, onload) {
+ui.readFile = function(file, onerror, onprogress, onload) {
     var reader = new FileReader();
     reader.onerror = function(e) {
         return onerror();
@@ -694,31 +1066,147 @@ ui.readfile = function(file, onerror, on
 };
 
 /**
+ * Draw an image on a canvas and convert it to a data URL.
+ */
+ui.drawImage = function(img, onload, width, height, crop) {
+    // Rotate an image
+    function rotate(icanvas, onload) {
+        debug('ui.drawImage.rotate');
+        var img = document.createElement('img');
+        img.onload = function() {
+            var canvas = document.createElement('canvas');
+            canvas.width = icanvas.height;
+            canvas.height = icanvas.width;
+            var ctx = canvas.getContext('2d');
+            ctx.setTransform(0, 1, -1, 0, icanvas.height, 0);
+            ctx.drawImage(img, 0, 0, icanvas.width, icanvas.height);
+            onload(canvas);
+        };
+        img.src = icanvas.toDataURL('image/png')
+        return true;
+    }
+
+    // Draw the image on a canvas and convert it to a JPEG data URL
+    function draw(img, onload, sx, sy, swidth, sheight, tx, ty, twidth, theight) {
+        debug('ui.drawImage.draw', sx, sy, swidth, sheight, tx, ty, twidth, theight);
+        var canvas = document.createElement('canvas');
+        canvas.width = twidth;
+        canvas.height = theight;
+        var ctx = canvas.getContext('2d');
+        ctx.drawImage(img, sx, sy, swidth, sheight, tx, ty, twidth, theight);
+        return onload(canvas);
+    }
+
+    // Resize and optionally crop an image
+    function resize(img, onload, width, height, oncrop) {
+        debug('ui.drawImage.resize');
+        var iwidth = img.width;
+        var iheight = img.height;
+        if (width || height || crop) {
+            if (crop) {
+                // Crop to fit target canvas size
+                var tratio = width / height;
+                var oratio = iwidth / iheight;
+                if (tratio > oratio) {
+                    var scale = width / iwidth;
+                    var cwidth = iwidth;
+                    var cheight = height / scale;
+                    var cut = (iheight - cheight) / 2;
+                    // Crop top and bottom edges, then resize
+                    return draw(img, onload, 0, cut, cwidth, cut + cheight, 0, 0, width, height);
+                } else if (tratio < oratio) {
+                    var scale = height / iheight;
+                    var cwidth = width / scale;
+                    var cheight = iheight;
+                    var cut = (iwidth - cwidth) / 2;
+                    // Crop left and right edges, then resize
+                    return draw(img, onload, cut, 0, cut + cwidth, cheight, 0, 0, width, height);
+                } else {
+                    // Just resize
+                    return draw(img, onload, 0, 0, iwidth, iheight, 0, 0, width, height);
+                }
+            } else {
+                // Resize to make the image fit
+                if (iwidth <= width && iheight == height) {
+                    return draw(img, onload, 0, 0, iwidth, iheight, 0, 0, iwidth, iheight);
+                } else {
+                    var tratio = width / height;
+                    var oratio = iwidth / iheight;
+                    if (tratio > oratio) {
+                        // Resize to make height fit
+                        var scale = height / iheight;
+                        var swidth = iwidth * scale;
+                        var sheight = height;
+                        return draw(img, onload, 0, 0, iwidth, iheight, 0, 0, swidth, sheight);
+                    } else if (tratio < oratio) {
+                        // Resize to make width fit
+                        var scale = width / iwidth;
+                        var swidth = width;
+                        var sheight = iheight * scale;
+                        return draw(img, onload, 0, 0, iwidth, iheight, 0, 0, swidth, sheight);
+                    } else {
+                        // Resize to make both width and height fit
+                        return draw(img, onload, 0, 0, iwidth, iheight, 0, 0, width, height);
+                    }
+                }
+            }
+        } else {
+            // Draw image as is
+            return draw(img, onload, 0, 0, iwidth, iheight, 0, 0, iwidth, iheight);
+        }
+    }
+
+    // Draw the image, optionally rotate, scale and crop it
+    (function drawImage() {
+        var iwidth = img.width;
+        var iheight = img.height;
+        document.body.removeChild(img);
+        var nwidth = img.width;
+        var nheight = img.height;
+        debug('ui.drawImage', 'img.width', iwidth, 'img.height', iheight, 'nwidth', nwidth, 'nheight', nheight, 'width', width, 'height', height, 'crop', crop);
+
+        if (iwidth != iheight && iwidth == nheight)
+            // Rotate and resize the image
+            return resize(img, function(canvas) {
+                return rotate(canvas, function(canvas) {
+                    return onload(canvas.toDataURL('image/jpeg', 0.95));
+                });
+            }, height, width, crop);
+        else {
+            // Just resize the image
+            return resize(img, function(canvas) {
+                return onload(canvas.toDataURL('image/jpeg', 0.95));
+            }, width, height, crop);
+        }
+    })();
+}
+
+/**
  * Read an image url and convert it to a data url.
  */
-ui.readimageurl = function(url, onerror, onprogress, onload, width, height) {
-    // Create a canvas to draw the image
-    var canvas = document.createElement('canvas');
-    if (width)
-        canvas.width = width;
-    if (height)
-        canvas.height = height;
+ui.readImageURL = function(url, onerror, onprogress, onload, width, height, crop) {
+    if(!width && !height && !crop && url.substring(0, 5) == 'data:') {
+        // Just use the given data URL if we're not resizing the image
+        debug('ui.readImageURL', 'original url');
+        onprogress(90);
+        ui.delay(function() {
+            return onload(url);
+        });
+        return true;
+    }
 
     // Create an image
-    var img = new Image();
+    var img = document.createElement('img');
+    ui.setStyle(img, 'visibility', 'hidden');
+    document.body.appendChild(img);
     img.onerror = function(e) {
+        document.body.removeChild(img);
         return onerror();
     };
     img.onload = function() {
         // Draw the image
-        var ctx = canvas.getContext('2d');
-        if (width || height)
-            ctx.drawImage(img, 0, 0, width, height);
-        else
-            ctx.drawImage(img, 0, 0);
-
-        // Convert new canvas image to a data url
-        return onload(canvas.toDataURL('image/png'));
+        debug('ui.readImageURL', 'new data url');
+        return ui.drawImage(img, onload, width, height, crop);
     };
 
     // Load the image
@@ -730,11 +1218,24 @@ ui.readimageurl = function(url, onerror,
 /**
  * Read an image file or url and convert it to a data url.
  */
-ui.readimage = function(img, onerror, onprogress, onload, width, height) {
+ui.readImageFile = function(img, onerror, onprogress, onload, width, height, crop) {
     if (isString(img))
-        return ui.readimageurl(img, onerror, onprogress, onload, width, height);
-    return ui.readfile(img, onerror, onprogress, function(url) {
-            return ui.readimageurl(url, onerror, onprogress, onload, width, height);
-        }, width, height);
+        return ui.readImageURL(img, onerror, onprogress, onload, width, height, crop);
+    return ui.readFile(img, onerror, onprogress, function onfile(url) {
+            return ui.readImageURL(url, onerror, onprogress, onload, width, height, crop);
+        });
+};
+
+/**
+ * Read an image and convert it to a data url.
+ */
+ui.readImage = function(img, onload, width, height, crop) {
+    if(!width && !height && img.src.substring(0, 5) == 'data:') {
+        // Just use the given data URL if we're not resizing the image
+        return onload(img.src);
+    }
+
+    // Draw the image
+    return ui.drawImage(img, onload, width, height, crop);
 };
 

Modified: tuscany/sca-cpp/trunk/modules/js/htdocs/util.js
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/htdocs/util.js?rev=1517415&r1=1517414&r2=1517415&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/htdocs/util.js (original)
+++ tuscany/sca-cpp/trunk/modules/js/htdocs/util.js Mon Aug 26 03:04:34 2013
@@ -24,235 +24,320 @@
 /**
  * Scheme-like lists.
  */
+function cell(car, cdr) {
+    this.car = car;
+    this.cdr = cdr;
+}
+
+cell.prototype.toString = function() {
+    return writeValue(this);
+};
+
 function cons(car, cdr) {
-    var a = new Array();
-    a.push(car);
-    return a.concat(cdr);
+    return new cell(car, cdr);
 }
 
-function car(l) {
-    return l[0];
+var nil = new cell(undefined, null);
+
+function mklist() {
+    if(arguments.length == 0)
+        return nil;
+    var l = nil;
+    for(var i = arguments.length - 1; i >= 0; i--)
+        l = cons(arguments[i], l);
+    return l;
 }
 
-function first(l) {
-    return l[0];
+function mkalist(a) {
+    if(a.length == 0)
+        return nil;
+    var l = nil;
+    for(var i = a.length - 1; i >= 0; i--)
+        l = cons(a[i], l);
+    return l;
 }
 
-function cdr(l) {
-    return l.slice(1);
+function car(l) {
+    if(l.cdr == null)
+        throw new Error('car out of bounds');
+        //error('car out of bounds');
+    return l.car;
 }
 
-function rest(l) {
-    return l.slice(1);
+function cdr(l) {
+    if(l.cdr == null)
+        throw new Error('cdr out of bounds');
+        //error('cdr out of bounds');
+    return l.cdr;
 }
 
 function cadr(l) {
-    return l[1];
+    return car(cdr(l));
 }
 
 function cddr(l) {
-    return l.slice(2);
+    return cdr(cdr(l));
 }
 
 function caddr(l) {
-    return l[2];
+    return car(cdr(cdr(l)));
 }
 
 function cdddr(l) {
-    return l.slice(3);
+    return cdr(cdr(cdr(l)));
 }
 
 function cadddr(l) {
-    return l[3];
+    return car(cdr(cdr(cdr(l))));
+}
+
+function last(l) {
+    if(l == nil)
+        throw new Error('last out of bounds');
+        //error('last out of bounds');
+    if(cdr(l) == nil)
+        return car(l);
+    return last(cdr(l));
 }
 
 function append(a, b) {
-    return a.concat(b);
+    if(a == nil)
+        return b;
+    return cons(car(a), append(cdr(a), b));
 }
 
 function reverse(l) {
-    return l.slice(0).reverse();
+    function reverseIter(acc, l) {
+        if(l == nil)
+            return acc;
+        return reverseIter(cons(car(l), acc), cdr(l));
+    }
+    return reverseIter(nil, l);
 }
 
-function range(a, b) {
-    var l = new Array();
-    for (var x = a; x < b; x++)
-        l.push(x);
-    return l;
+function seq(start, end) {
+    if(start == end)
+        return mklist(start);
+    if(start < end)
+        return cons(start, seq(start + 1, end));
+    return cons(start, seq(start - 1, end));
 }
 
 function isNull(v) {
-    return (v == null || typeof v == 'undefined' || (v.constructor == Array && v.length == 0));
+    return v == nil || v == null || typeof v == 'undefined';
 }
 
 function isSymbol(v) {
-    return (typeof v == 'string' && v.slice(0, 1) == "'");
+    return typeof v == 'string' && v[0] == "'";
 }
 
 function isString(v) {
-    return (typeof v == 'string' && v.slice(0, 1) != "'");
+    return typeof v == 'string' && v[0] != "'";
 }
 
 function isList(v) {
-    return (v != null && typeof v != 'undefined' && v.constructor == Array);
+    return v != null && typeof v != 'undefined' && typeof v.cdr != 'undefined';
 }
 
 function isTaggedList(v, t) {
-    return (isList(v) && !isNull(v) && car(v) == t);
+    return isList(v) && v != nil && car(v) == t;
 }
 
-var emptylist = new Array();
-
-function mklist() {
-    if (arguments.length == 0)
-        return emptylist;
-    var a = new Array();
-    for (i = 0; i < arguments.length; i++)
-        a[i] = arguments[i];
-    return a;
+function mkarray(l) {
+    return reduce(function(a, v) {
+        a[a.length] = v;
+        return a;
+    }, [], l);
 }
 
 function length(l) {
-    return l.length;
+    function lengthRef(c, l) {
+        if(l == nil)
+            return c;
+        return lengthRef(c + 1, cdr(l));
+    }
+    return lengthRef(0, l);
 }
 
 /**
  * Scheme-like associations.
  */
 function assoc(k, l) {
-    if (isNull(l))
-        return emptylist;
-    var n = l.length;
-    for(var i = 0; i < n; i++) {
-        if (k == car(l[i]))
-            return l[i];
-    }
-    return emptylist;
+    if(l == nil)
+        return nil;
+    var c = car(l);
+    if(isList(c) && c != nil  && k == car(c))
+        return c;
+    return assoc(k, cdr(l));
 }
 
 /**
  * Map, filter and reduce functions.
  */
 function map(f, l) {
-    if (isNull(l))
-        return l;
-    var n = l.length;
-    var a = new Array();
-    for(var i = 0; i < n; i++) {
-        a.push(f(l[i]));
-    }
-    return a;
+    if(l == nil)
+        return nil;
+    return cons(f(car(l)), map(f, cdr(l)));
 }
 
 function filter(f, l) {
-    if (isNull(l))
-        return l;
-    var n = l.length;
-    var a = new Array();
-    for(var i = 0; i < n; i++) {
-        if (f(l[i]))
-            a.push(l[i]);
-    }
-    return a;
+    if(l == nil)
+        return nil;
+    if (f(car(l)))
+        return cons(car(l), filter(f, cdr(l)));
+    return filter(f, cdr(l));
 }
 
 function reduce(f, i, l) {
-    if (isNull(l))
-        return i;
-    return reduce(f, f(i, car(l)), cdr(l));
+    function reduceAccumulate(acc, l) {
+        if(l == nil)
+            return acc;
+        return reduceAccumulate(f(acc, car(l)), cdr(l));
+    };
+    return reduceAccumulate(i, l);
 }
 
 /**
- * Split a path into a list of segments.
+ * Sort.
  */
+function sort(f, l) {
+    return mkalist(mkarray(l).sort(f));
+}
+
+/**
+ * String split, join and tokenize functions.
+ */
+function split(s, d) {
+    return mkalist(s.split(d));
+}
+
+function join(l, d) {
+    return mkarray(l).join(d);
+}
+
 function tokens(path) {
-    return filter(function(s) { return length(s) != 0; }, path.split("/"));
+    return filter(function(s) { return s.length != 0; }, split(path, '/'));
 }
 
 /**
- * Debug log a value.
+ * Log values to debug log.
  */
-var rconsole;
+if(window.debugging == undefined)
+    window.debugging = false;
+var remoteLog;
+var bufferedLog;
+ 
+function debug() {
+    if (!window.debugging)
+        return false;
+    var s = '';
+    for(var i = 0; i < arguments.length; i++) {
+        s += writeValue(arguments[i]);
+        if(i < arguments.length)
+            s += ' ';
+    }
+    if(remoteLog)
+        remoteLog.log(s);
+    if (bufferedLog)
+        bufferedLog[bufferedLog.length] = s;
+    return console.log(s);
+}
 
-function debug(v) {
-    try {
-        var s = '';
-        for (i = 0; i < arguments.length; i++) {
-            s = s + writeValue(arguments[i]);
-            if (i < arguments.length)
-                s = s + ' ';
+function error() {
+    var s = '';
+    for(var i = 0; i < arguments.length; i++) {
+        s += writeValue(arguments[i]);
+        var a = arguments[i];
+        if(a != null && typeof a == 'object' && typeof a.stack != 'undefined') {
+            s += ' ';
+            s += writeValue(a.stack);
         }
+        if(i < arguments.length)
+            s = s + ' ';
+    }
 
-        if (rconsole) {
-            try {
-                rconsole.log(s);
-            } catch (e) {}
-        }
-        try {
-            console.log(s);
-        } catch (e) {}
-    } catch (e) {}
+    if(remoteLog)
+        remoteLog.error(s);
+    if (bufferedLog) {
+        try { throw new Error(); } catch(t) { bufferedLog[bufferedLog.length] = writeValue(t.stack); }
+        bufferedLog[bufferedLog.length] = s;
+    }
+    return console.error(s);
+}
+
+/**
+ * Log uncaught errors.
+ */
+if (typeof window != 'undefined') {
+    window.onerror = function(msg, url, line) {
+        error('window.onerror', msg, url, line);
+        return false;
+    };
+}
+
+/**
+ * Buffer log entries in memory.
+ */
+function bufferLog() {
+    bufferedLog = [];
+    return true;
+}
+
+function printLog() {
+    if (!bufferedLog)
+        return false;
+    for(var i in bufferedLog)
+        console.log(bufferedLog[i]);
+    return true;
+}
+
+function clearLog() {
+    bufferedLog = [];
     return true;
 }
 
 /**
- * Dump an object to the console.
+ * Dump an object to the log.
  */
 function dump(o) {
-    try {
-        for (f in o) {
-            try {
-                debug('dump ' + f + '=' + o[f]);
-            } catch (e) {}
-        }
-    } catch (e) {}
+    if (!window.debugging)
+        return false;
+    for(var f in o)
+        debug('dump', f, '=', o[f]);
     return true;
 }
 
 /**
  * Return true if the current browser is Internet Explorer.
  */
-function isIE() {
-    if (typeof isIE.detected != 'undefined')
-        return isIE.detected;
-    isIE.detected = navigator.appName == 'Microsoft Internet Explorer';
-    return isIE.detected;
-};
+function isMSIE() {
+    if(typeof isMSIE.detected != 'undefined')
+        return isMSIE.detected;
+    isMSIE.detected = navigator.userAgent.match(/MSIE/i);
+    return isMSIE.detected;
+}
 
 /**
  * External build configuration.
  */
 var config;
-if (isNull(config))
+if(isNull(config))
     config = {};
 
 /**
- * Simple assert function.
+ * Assertion.
  */
-function AssertException() {
-}
-
-AssertException.prototype.toString = function () {
-    return 'AssertException';
-};
-
 function assert(exp) {
-    if (!exp)
-        throw new AssertException();
+    if(!exp)
+        throw new Error('assertion failed');
+    return true;
 }
 
 /**
  * Write a list of strings.
  */
 function writeStrings(l) {
-    if (isNull(l))
-        return '';
-    var s = '';
-    var n = l.length;
-    for(var i = 0; i < n; i++) {
-        s = s + l[i];
-    }
-    return s;
+    return reduce(function(a, s) { return a + s; }, '', l);
 }
 
 /**
@@ -260,22 +345,22 @@ function writeStrings(l) {
  */
 function writeValue(v) {
     function writePrimitive(p) {
-        if (isSymbol(p))
+        if(isSymbol(p))
             return '' + p.substring(1);
-        if (isString(p))
+        if(isString(p))
             return '"' + p + '"';
         return '' + p;
     }
 
     function writeList(l) {
-        if (isNull(l))
+        if(l == nil)
             return '';
         return ' ' + writeValue(car(l)) + writeList(cdr(l));
     }
 
-    if (!isList(v))
+    if(!isList(v))
         return writePrimitive(v);
-    if (isNull(v))
+    if(v == nil)
         return '()';
     return '(' + writeValue(car(v)) + writeList(cdr(v)) + ')';
 }
@@ -284,11 +369,11 @@ function writeValue(v) {
  * Apply a function and memoize its result.
  */
 function memo(obj, key, f) {
-    if (!('memo' in obj)) {
+    if(typeof obj.memo == 'undefined') {
         obj.memo = {};
         return obj.memo[key] = f();
     }
-    if (key in obj.memo)
+    if(key in obj.memo)
         return obj.memo[key];
     return obj.memo[key] = f();
 }
@@ -297,18 +382,19 @@ function memo(obj, key, f) {
  * Un-memoize stored results.
  */
 function unmemo(obj, prefix) {
-    if (!prefix) {
+    if(!prefix) {
         obj.memo = {};
         return true;
     }
-    if (!('memo' in obj)) {
+    if(typeof obj.memo == 'undefined') {
         obj.memo = {};
         return true;
     }
-    for (key in obj.memo) {
-        if (key.substring(0, prefix.length) == prefix)
+    for(var key in obj.memo) {
+        if(key.substring(0, prefix.length) == prefix)
             delete obj.memo[key];
     }
+    return true;
 }
 
 /**
@@ -321,115 +407,112 @@ lstorage.enabled = true;
  * Get a key.
  */
 lstorage.key = function(i) {
-    if (!lstorage.enabled)
-        return null;
-    try {
-        return localStorage.key(i);
-    } catch(e) {
-        return null;
-    }
+    if(!lstorage.enabled)
+        return undefined;
+    return localStorage.key(i);
 };
 
 /**
  * Return the number of keys.
  */
 lstorage.length = function() {
-    if (!lstorage.enabled)
-        return 0;
-    try {
-        return localStorage.length;
-    } catch(e) {
+    if(!lstorage.enabled)
         return 0;
-    }
+    return localStorage.length;
 };
 
 /**
  * Get an item.
  */
 lstorage.getItem = function(k) {
-    if (!lstorage.enabled)
-        return null;
-    try {
-        return localStorage.getItem(k);
-    } catch(e) {
-        return null;
-    }
+    if(!lstorage.enabled)
+        return undefined;
+    return localStorage.getItem(k);
 };
 
 /**
  * Set an item.
  */
 lstorage.setItem = function(k, v) {
-    if (!lstorage.enabled)
-        return null;
-    try {
+    if(!lstorage.enabled)
+        return v;
+    if (localStorage.getItem(k) != v)
         return localStorage.setItem(k, v);
-    } catch(e) {
-        return null;
-    }
+    else
+        return v;
 };
 
 /**
  * Remove an item.
  */
 lstorage.removeItem = function(k) {
-    if (!lstorage.enabled)
-        return null;
-    try {
-        return localStorage.removeItem(k);
-    } catch(e) {
-        return null;
-    }
+    if(!lstorage.enabled)
+        return undefined;
+    return localStorage.removeItem(k);
 };
 
 /**
  * Returns a list of the properties of an object.
  */
 function properties(o) {
-    var a = new Array();
-    for (p in o)
-        a.push(p);
-    return a;
+    var l = nil;
+    for(var p in o)
+        l = cons(p, l);
+    return reverse(l);
+}
+
+/**
+ * Convert a DOM node list to a regular list.
+ */
+function nodeList(n) {
+    if (n == null || n.length == 0)
+        return nil;
+    var l = nil;
+    for (var i = n.length - 1; i >= 0; i--)
+        l = cons(n[i], l);
+    return l;
 }
 
 /**
  * Convert a host name to a domain name.
  */
-function domainname(host) {
+function domainName(host) {
     var ds = host.indexOf('//');
-    if (ds != -1)
-        return domainname(host.substring(ds + 2));
+    if(ds != -1)
+        return domainName(host.substring(ds + 2));
     var s = host.indexOf('/');
-    if (s != -1)
-        return domainname(host.substring(0, s));
-    var h = reverse(host.split('.'));
-    var d = (!isNull(cddr(h)) && caddr(h) == 'www')? mklist(car(h), cadr(h), caddr(h)) : mklist(car(h), cadr(h));
-    return reverse(d).join('.');
+    if(s != -1)
+        return domainName(host.substring(0, s));
+    var h = reverse(split(host, '.'));
+    var d = (cddr(h) != nil && caddr(h) == 'www')? mklist(car(h), cadr(h), caddr(h)) : mklist(car(h), cadr(h));
+    return join(reverse(d), '.');
 }
 
 /**
  * Convert a host name to a top domain name.
  */
-function topdomainname(host) {
-    var d = reverse(domainname(host).split('.'));
-    return reverse(mklist(car(d), cadr(d))).join('.');
+function topDomainName(host) {
+    var d = reverse(split(domainName(host),'.'));
+    return join(mklist(car(d), cadr(d)), '.');
 }
 
 /**
  * Return true if a host name is a subdomain.
  */
-function issubdomain(host) {
-    return host.split('.').length > 2;
+function isSubDomain(host) {
+    return length(split(host, '.')) > 2;
 }
 
 /**
  * Clear auth information from the document cookie.
  */
-function clearauthcookie() {
-    document.cookie = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/; secure; httponly';
-    document.cookie = 'TuscanyOAuth1=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/; secure; httponly';
-    document.cookie = 'TuscanyOAuth2=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/; secure; httponly';
-    document.cookie = 'TuscanyOpenIDAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/; secure; httponly';
+function clearAuthCookie() {
+    var d = new Date(1970,01,01).toGMTString();
+    var dn = domainName(window.location.hostname);
+    document.cookie = 'TuscanyOpenAuth=; expires=' + d + '; domain=.' + dn + '; path=/; secure; httponly';
+    document.cookie = 'TuscanyOAuth1=; expires=' + d + '; domain=.' + dn + '; path=/; secure; httponly';
+    document.cookie = 'TuscanyOAuth2=; expires=' + d + '; domain=.' + dn + '; path=/; secure; httponly';
+    document.cookie = 'TuscanyOpenIDAuth=; expires=' + d + '; domain=.' + dn + '; path=/; secure; httponly';
     return true;
 }
 
@@ -439,7 +522,7 @@ function clearauthcookie() {
 function format() {
     var i = 0;
     var s = '';
-    for (a in arguments) {
+    for(var a = 0; a < arguments.length; a++) {
         s = i == 0? arguments[a] : s.replace('{' + a + '}', arguments[a]);
         i++;
     }
@@ -449,10 +532,10 @@ function format() {
 /**
  * Parse an XML dateTime.
  */
-function xmldatetime(xml) {
+function xmlDateTime(xml) {
     var re = /^([0-9]{4,})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(\.[0-9]+)?(Z|([+-])([0-9]{2}):([0-9]{2}))?$/;
     var match = xml.match(re);
-    if (!match)
+    if(!match)
         return new Date();
     return new Date(Date.UTC(match[1], parseInt(match[2]) - 1, match[3],
                 match[9]? parseInt(match[4]) + parseInt(match[10]) * (match[9] == '+'? 1 : -1) : match[4],
@@ -463,14 +546,14 @@ function xmldatetime(xml) {
 /**
  * Encode a string to a url-safe base64 format.
  */
-function safeb64encode(s) {
+function safeB64Encode(s) {
     return btoa(s).replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, '');
 }
 
 /**
  * Decode a url-safe base64 encoded string.
  */
-function safeb64decode(s) {
+function safeB64Decode(s) {
     return atob((s.replace(/\-/g, '+').replace(/\_/g, '/') + '===').substring(0, s.length + (s.length % 4)));
 }
 
@@ -478,7 +561,7 @@ function safeb64decode(s) {
  * Return a uuid4.
  */
 function uuid4() {
-    if (window.crypto && window.crypto.getRandomValues) {
+    if(window.crypto && window.crypto.getRandomValues) {
         var b = new Uint16Array(8);
         window.crypto.getRandomValues(b);
         function s4(n) {
@@ -497,9 +580,9 @@ function uuid4() {
 /**
  * Convert an hexadecimal string to ascii.
  */
-function hex2ascii(x) {
+function hex2Ascii(x) {
     var a = '';
-    for (var i = 0; i < x.length; i += 2)
+    for(var i = 0; i < x.length; i += 2)
         a += String.fromCharCode(parseInt(x.substr(i, 2), 16));
     return a;
 }
@@ -512,7 +595,7 @@ function hex2ascii(x) {
  * Set the car of a list.
  */
 function setcar(l, v) {
-    l[0] = v;
+    l.car = v;
     return l;
 }
 
@@ -520,7 +603,7 @@ function setcar(l, v) {
  * Set the cadr of a list.
  */
 function setcadr(l, v) {
-    l[1] = v;
+    l.cdr.car = v;
     return l;
 }
 
@@ -528,35 +611,104 @@ function setcadr(l, v) {
  * Set the caddr of a list.
  */
 function setcaddr(l, v) {
-    l[2] = v;
+    l.cdr.cdr.car = v;
     return l;
 }
 
 /**
- * Append the elements of a list to a list.
+ * Set the cdr of a list.
  */
-function setappend(a, b) {
-    if (isNull(b))
-        return a;
-    a.push(car(b));
-    return setappend(a, cdr(b));
+function setcdr(a, b) {
+    a.cdr = b;
+    return a;
 }
 
 /**
- * Set the cdr of a list.
+ * Set the contents of a list.
  */
-function setcdr(a, b) {
-    a.length = 1;
-    return setappend(a, b);
+function setList(a, b) {
+    if(b == a)
+        return a;
+    a.car = b.car;
+    a.cdr = b.cdr;
+    return a;
 }
 
 /**
- * Set the contents of a list.
+ * Append the elements of a list to a list.
  */
-function setlist(a, b) {
-    if (b == a)
-        return b;
-    a.length = 0;
-    return setappend(a, b);
+function setAppend(a, b) {
+    if(b.cdr == null)
+        return a;
+    return setList(a, append(a, b));
 }
 
+/**
+ * Uncomment to run the tests.
+ */
+/*
+(function testUtil() {
+    console.log('Testing...');
+
+    assert(car(cons(1, nil)) == 1);
+    assert(car(mklist(1)) == 1);
+    assert(cadr(mklist(1, 2)) == 2);
+
+    assert(0 == length(nil));
+    assert(1 == length(mklist(1)));
+    assert(2 == length(cons(1, mklist(2))));
+
+    assert(car(append(mklist(1), mklist(2))) == 1);
+    assert(car(cdr(append(mklist(1), mklist(2)))) == 2);
+    assert(car(cdr(cdr(append(mklist(1), mklist(2, 3))))) == 3);
+    assert(isNull(cdr(cdr(cdr(append(mklist(1), mklist(2, 3)))))));
+    assert(last(mklist(1, 2, 3)) == 3);
+    assert('' + mklist(1, 2, 3) == '(1 2 3)');
+
+    function square(v) { return v * v; }
+    assert(isNull(map(square, nil)));
+    var m = map(square, mklist(2, 3));
+    assert(car(m) == 4);
+    assert(car(cdr(m)) == 9);
+
+    function add(x, y) { return x + y; }
+    assert(reduce(add, 0, mklist(1, 2, 3)) == 6);
+
+    function isPositive(x) { return x >= 0; }
+    assert(car(filter(isPositive, mklist(1, -1, 2, -2))) == 1);
+    assert(cadr(filter(isPositive, mklist(1, -1, 2, -2))) == 2);
+
+    assert(isNull(reverse(nil)));
+    assert(car(reverse(mklist(1, 2, 3))) == 3);
+    assert(cadr(reverse(mklist(1, 2, 3))) == 2);
+
+    var l = mklist(mklist('x', 'X'), mklist('a', 'A'), mklist('y', 'Y'), mklist('a', 'AA'));
+    assert(car(assoc('a', l)) == 'a');
+    assert(isNull(assoc('z', l)));
+
+    var s = seq(0.0, 1000.0);
+    assert(1001 == length(s));
+    function seqreduce(acc, v) { return acc + 1.0; }
+    assert(1001 == reduce(seqreduce, 0.0, s));
+
+    function compare(a, b) { return a < b? -1 : a == b? 0 : 1; }
+    var l2 = sort(compare, mklist(4, 3, 1, 2));
+    assert(car(l2) == 1);
+    assert(last(l2) == 4);
+
+    var t = new Date();
+    var p = nil;
+    for(var i = 0; i < 100000; i++) {
+        p = cons(i, p);
+    }
+    for(var i = 0; i < 100000; i++) {
+        var x = car(p);
+        p = cdr(p);
+    }
+    console.log('list perf', new Date() - t, 'ms');
+
+    console.log('OK');
+    return true;
+})();
+*/
+

Modified: tuscany/sca-cpp/trunk/modules/js/htdocs/xmlutil.js
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/htdocs/xmlutil.js?rev=1517415&r1=1517414&r2=1517415&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/htdocs/xmlutil.js (original)
+++ tuscany/sca-cpp/trunk/modules/js/htdocs/xmlutil.js Mon Aug 26 03:04:34 2013
@@ -22,18 +22,6 @@
  */
 
 /**
- * Convert a DOM node list to a regular list.
- */
-function nodeList(n) {
-    var l = new Array();
-    if (isNull(n))
-        return l;
-    for (var i = 0; i < n.length; i++)
-        l[i] = n[i];
-    return l;
-}
-
-/**
  * Append a list of nodes to a parent node.
  */
 function appendNodes(nodes, p) {
@@ -41,7 +29,7 @@ function appendNodes(nodes, p) {
         return p;
     p.appendChild(car(nodes));
     return appendNodes(cdr(nodes), p);
-};
+}
 
 /**
  * Return the child attributes of an element.
@@ -61,31 +49,29 @@ function childElements(e) {
  * Return the child text nodes of an element.
  */
 function childText(e) {
-    function trim(s) {
-        return s.replace(/^\s*/, '').replace(/\s*$/, '');
-    }
-    return filter(function(n) { return n.nodeType == 3 && trim(n.nodeValue) != ''; }, nodeList(e.childNodes));
+    return filter(function(n) { return n.nodeType == 3 && n.nodeValue.trim().length != 0; }, nodeList(e.childNodes));
 }
 
 /**
  * Read a list of XML attributes.
  */
-function readAttributes(p, a) {
+function readAttributes(a) {
     if (isNull(a))
         return a;
     var x = car(a);
-    return cons(mklist(attribute, "'" + x.nodeName, x.nodeValue), readAttributes(p, cdr(a)));
+    return cons(mklist(attribute, "'" + x.name, x.value), readAttributes(cdr(a)));
 }
 
 /**
  * Read an XML element.
  */
 function readElement(e, childf) {
-    var l = append(append(mklist(element, "'" + e.nodeName), readAttributes(e, childf(e))), readElements(childElements(e), childf));
+    var l = append(append(mklist(element, "'" + e.nodeName), readAttributes(childf(e))), readElements(childElements(e), childf));
     var t = childText(e);
     if (isNull(t))
         return l;
-    return append(l, mklist(car(t).nodeValue));
+    var tv = reduce(function(a, n) { return a + n.nodeValue; }, '', t);
+    return append(l, mklist(tv));
 }
 
 /**
@@ -109,10 +95,10 @@ function isXML(l) {
 /**
  * Parse a list of strings representing an XML document.
  */
+var xmlParser = new DOMParser();
 function parseXML(l) {
     var s = writeStrings(l);
-    var p = new DOMParser();
-    return p.parseFromString(s, "text/xml");
+    return xmlParser.parseFromString(s, "text/xml");
 }
 
 /**
@@ -121,7 +107,7 @@ function parseXML(l) {
 function readXMLDocument(doc) {
     var root = childElements(doc);
     if (isNull(root))
-        return mklist();
+        return nil;
     return mklist(readElement(car(root), childAttributes));
 }
 
@@ -129,29 +115,7 @@ function readXMLDocument(doc) {
  * Read a list of values from an XHTML element.
  */
 function readXHTMLElement(xhtml) {
-    // Special XHTML attribute filtering on IE
-    function ieChildAttributes(e) {
-        var a = filter(function(n) {
-            // Filter out empty and internal DOM attributes
-            if (n.nodeType != 2 || isNull(n.nodeValue) || n.nodeValue == '')
-                return false;
-            if (n.nodeName == 'contentEditable' || n.nodeName == 'maxLength' || n.nodeName == 'loop' || n.nodeName == 'start')
-                return false;
-            return true;
-        }, nodeList(e.attributes));
-
-        if (e.style.cssText == '')
-            return a;
-
-        // Add style attribute
-        var sa = new Object();
-        sa.nodeName = 'style';
-        sa.nodeValue = e.style.cssText;
-        return cons(sa, a);
-    }
-
-    var childf = (typeof(XMLSerializer) != 'undefined')? childAttributes : ieChildAttributes;
-    return mklist(readElement(xhtml, childf));
+    return mklist(readElement(xhtml, childAttributes));
 }
 
 /**
@@ -164,10 +128,9 @@ function readXML(l) {
 /**
  * Return a list of strings representing an XML document.
  */
+var xmlSerializer = new XMLSerializer();
 function writeXMLDocument(doc) {
-    if (typeof(XMLSerializer) != 'undefined')
-        return mklist(new XMLSerializer().serializeToString(doc));
-    return mklist(doc.xml);
+    return mklist(xmlSerializer.serializeToString(doc));
 }
 
 /**
@@ -185,7 +148,7 @@ function writeList(l, node, doc) {
 
     var token = car(l);
     if (isTaggedList(token, attribute)) {
-        if (isIE()) {
+        if (isMSIE()) {
             var aname = attributeName(token).substring(1);
             if (aname != 'xmlns')
                 node.setAttribute(aname, '' + attributeValue(token));
@@ -207,7 +170,7 @@ function writeList(l, node, doc) {
             }
 
             var ns = xmlns(elementChildren(tok));
-            if (isIE())
+            if (isMSIE())
                 return doc.createElementNS(ns != null? ns : node.namespaceURI, elementName(tok).substring(1));
             if (ns == null)
                 return doc.createElement(elementName(tok).substring(1));
@@ -251,6 +214,6 @@ function writeXML(l, xmlTag) {
     writeList(l, doc, doc);
     if (!xmlTag)
         return writeXMLDocument(doc);
-    return mklist('<?xml version="1.0" encoding="UTF-8"?>\n' + writeXMLDocument(doc) + '\n');
+    return mklist('<?xml version="1.0" encoding="UTF-8"?>\n' + car(writeXMLDocument(doc)) + '\n');
 }
 

Modified: tuscany/sca-cpp/trunk/modules/js/js-conf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/js-conf?rev=1517415&r1=1517414&r2=1517415&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/js-conf (original)
+++ tuscany/sca-cpp/trunk/modules/js/js-conf Mon Aug 26 03:04:34 2013
@@ -26,8 +26,10 @@ cat >>$root/conf/httpd.conf <<EOF
 # Generated by: js-conf $*
 # Serve JavaScript scripts and CSS
 Alias /ui-min.css $here/htdocs/ui-min.css
+Alias /base-min.js $here/htdocs/base-min.js
 Alias /all-min.js $here/htdocs/all-min.js
 Alias /proxy/ui-min.css $here/htdocs/ui-min.css
+Alias /proxy/base-min.js $here/htdocs/base-min.js
 Alias /proxy/all-min.js $here/htdocs/all-min.js
 
 EOF
@@ -39,6 +41,11 @@ AuthType None
 Session Off
 Require all granted
 </Location>
+<Location /base-min.js>
+AuthType None
+Session Off
+Require all granted
+</Location>
 <Location /all-min.js>
 AuthType None
 Session Off
@@ -49,6 +56,11 @@ AuthType None
 Session Off
 Require all granted
 </Location>
+<Location /proxy/base-min.js>
+AuthType None
+Session Off
+Require all granted
+</Location>
 <Location /proxy/all-min.js>
 AuthType None
 Session Off

Copied: tuscany/sca-cpp/trunk/modules/js/js-extract (from r1517414, tuscany/sca-cpp/trunk/modules/js/Makefile.am)
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/js-extract?p2=tuscany/sca-cpp/trunk/modules/js/js-extract&p1=tuscany/sca-cpp/trunk/modules/js/Makefile.am&r1=1517414&r2=1517415&rev=1517415&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/Makefile.am (original)
+++ tuscany/sca-cpp/trunk/modules/js/js-extract Mon Aug 26 03:04:34 2013
@@ -1,3 +1,5 @@
+#!/bin/sh
+
 #  Licensed to the Apache Software Foundation (ASF) under one
 #  or more contributor license agreements.  See the NOTICE file
 #  distributed with this work for additional information
@@ -15,31 +17,7 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
+# Extract <script/> sections from an HTML file
 
-jsfiles = htdocs/util.js htdocs/elemutil.js htdocs/xmlutil.js htdocs/atomutil.js htdocs/jsonutil.js htdocs/scdl.js htdocs/ui.js htdocs/component.js
-
-BUILT_SOURCES = htdocs/all.js
-htdocs/all.js: ${jsfiles}
-	cat $^ >htdocs/all.js
-
-minified = htdocs/all-min.js htdocs/ui-min.css
-
-SUFFIXES = -min.html -min.js -min.css
-.html-min.html:
-	../../modules/http/minify-html $< $@
-
-.js-min.js:
-	../../modules/http/minify-js $< $@
-
-.css-min.css:
-	../../modules/http/minify-css $< $@
-
-CLEANFILES = htdocs/all.js ${minified}
-
-dist_mod_SCRIPTS = js-conf
-moddir = $(prefix)/modules/js
-nobase_dist_mod_DATA = ${minified}
-EXTRA_DIST = ${jsfiles} htdocs/ui.css
-
-dist_noinst_SCRIPTS = util-test
+awk 'BEGIN { s=0; } /<\/script>/ { s=0; } { if (s == 1) { print; } } /<script / { s=1; } /<script .*<\/script>/ { s=0; }'
 

Propchange: tuscany/sca-cpp/trunk/modules/js/js-extract
------------------------------------------------------------------------------
    svn:executable = *

Added: tuscany/sca-cpp/trunk/patches/page-speed-1.9.patch
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/patches/page-speed-1.9.patch?rev=1517415&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/patches/page-speed-1.9.patch (added)
+++ tuscany/sca-cpp/trunk/patches/page-speed-1.9.patch Mon Aug 26 03:04:34 2013
@@ -0,0 +1,11 @@
+--- third_party/instaweb/src/net/instaweb/rewriter/elide_attributes_filter.cc
++++ third_party/instaweb/src/net/instaweb/rewriter/elide_attributes_filter.cc
+@@ -82,7 +82,7 @@
+ 
+ const TagAttrValue kDefaultList[] = {
+   {"script", "language", NULL},
+-  {"script", "type", NULL},
++  {"script", "type", "text/javascript"},
+   {"style", "type", NULL},
+   {"br", "clear", "none"},
+   {"a", "shape", "rect"},

Modified: tuscany/sca-cpp/trunk/ubuntu/ubuntu-install-all
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/ubuntu/ubuntu-install-all?rev=1517415&r1=1517414&r2=1517415&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/ubuntu/ubuntu-install-all (original)
+++ tuscany/sca-cpp/trunk/ubuntu/ubuntu-install-all Mon Aug 26 03:04:34 2013
@@ -416,6 +416,8 @@ cd $build
 curl -OL https://dl-ssl.google.com/page-speed/sdk/current/page-speed-sdk.zip
 unzip page-speed-sdk.zip
 cd page-speed-1.9
+curl -OL http://svn.apache.org/repos/asf/tuscany/sca-cpp/trunk/patches/page-speed-1.9.patch
+patch -p0 <page-speed-1.9.patch
 make builddir=$build/page-speed-1.9-bin CXXFLAGS="-Wno-unused-but-set-variable"
 if [ "$?" != "0" ]; then
     exit $?

Modified: tuscany/sca-cpp/trunk/ubuntu/ubuntu-install-nothreads
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/ubuntu/ubuntu-install-nothreads?rev=1517415&r1=1517414&r2=1517415&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/ubuntu/ubuntu-install-nothreads (original)
+++ tuscany/sca-cpp/trunk/ubuntu/ubuntu-install-nothreads Mon Aug 26 03:04:34 2013
@@ -311,6 +311,8 @@ cd $build
 curl -OL https://dl-ssl.google.com/page-speed/sdk/current/page-speed-sdk.zip
 unzip page-speed-sdk.zip
 cd page-speed-1.9
+curl -OL http://svn.apache.org/repos/asf/tuscany/sca-cpp/trunk/patches/page-speed-1.9.patch
+patch -p0 <page-speed-1.9.patch
 make builddir=$build/page-speed-1.9-bin CXXFLAGS="-Wno-unused-but-set-variable"
 if [ "$?" != "0" ]; then
     exit $?