summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sca-cpp/trunk/.gitignore3
-rw-r--r--sca-cpp/trunk/modules/http/Makefile.am2
-rwxr-xr-xsca-cpp/trunk/modules/http/ssinclude-html28
-rw-r--r--sca-cpp/trunk/modules/js/Makefile.am11
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/component.js591
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/jsonutil.js100
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/ui.css1032
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/ui.js913
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/util.js576
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/xmlutil.js69
-rwxr-xr-xsca-cpp/trunk/modules/js/js-conf12
-rwxr-xr-xsca-cpp/trunk/modules/js/js-extract23
-rw-r--r--sca-cpp/trunk/patches/page-speed-1.9.patch11
-rwxr-xr-xsca-cpp/trunk/ubuntu/ubuntu-install-all2
-rwxr-xr-xsca-cpp/trunk/ubuntu/ubuntu-install-nothreads2
15 files changed, 1724 insertions, 1651 deletions
diff --git a/sca-cpp/trunk/.gitignore b/sca-cpp/trunk/.gitignore
index 42539a1488..3cc1c02ade 100644
--- a/sca-cpp/trunk/.gitignore
+++ b/sca-cpp/trunk/.gitignore
@@ -57,11 +57,14 @@ config.guess
config.sub
config.status
all.js
+base.js
cache-manifest.cmf
*-min.html
+*-ssi.html
*-min.js
*-min.css
*.b64
+*.off
intro*.png
depcomp
install-sh
diff --git a/sca-cpp/trunk/modules/http/Makefile.am b/sca-cpp/trunk/modules/http/Makefile.am
index 42504d57ec..273464ee8a 100644
--- a/sca-cpp/trunk/modules/http/Makefile.am
+++ b/sca-cpp/trunk/modules/http/Makefile.am
@@ -20,7 +20,7 @@ INCLUDES = -I${HTTPD_INCLUDE}
incl_HEADERS = *.hpp
incldir = $(prefix)/include/modules/http
-dist_mod_SCRIPTS = httpd-conf httpd-addr httpd-start httpd-stop httpd-restart ssl-ca-conf ssl-cert-conf ssl-cert-find httpd-ssl-conf base64-encode basic-auth-conf cert-auth-conf form-auth-conf open-auth-conf passwd-auth-conf group-auth-conf cache-conf cache-ssl-conf cache-manifest proxy-conf proxy-base-conf proxy-ssl-conf proxy-balancer-conf proxy-member-conf proxy-ssl-member-conf proxy-ssl-nossl-member-conf alt-host-conf mass-host-conf mass-host-ssl-conf httpd-tunnel-ssl-conf tunnel-ssl-conf httpd-worker-conf httpd-event-conf httpd-loglevel-conf minify-html minify-js minify-css
+dist_mod_SCRIPTS = httpd-conf httpd-addr httpd-start httpd-stop httpd-restart ssl-ca-conf ssl-cert-conf ssl-cert-find httpd-ssl-conf base64-encode basic-auth-conf cert-auth-conf form-auth-conf open-auth-conf passwd-auth-conf group-auth-conf cache-conf cache-ssl-conf cache-manifest proxy-conf proxy-base-conf proxy-ssl-conf proxy-balancer-conf proxy-member-conf proxy-ssl-member-conf proxy-ssl-nossl-member-conf alt-host-conf mass-host-conf mass-host-ssl-conf httpd-tunnel-ssl-conf tunnel-ssl-conf httpd-worker-conf httpd-event-conf httpd-loglevel-conf minify-html minify-js minify-css ssinclude-html
moddir = $(prefix)/modules/http
curl_test_SOURCES = curl-test.cpp
diff --git a/sca-cpp/trunk/modules/http/ssinclude-html b/sca-cpp/trunk/modules/http/ssinclude-html
new file mode 100755
index 0000000000..63b524d7b4
--- /dev/null
+++ b/sca-cpp/trunk/modules/http/ssinclude-html
@@ -0,0 +1,28 @@
+#!/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
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Process server-side includes in an HTML file
+here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
+
+html=`echo "import os; print os.path.realpath('$1')" | python`
+ssihtml=`echo "import os; print os.path.realpath('$2')" | python`
+
+cd `dirname ${html}`
+cat ${html} | awk '{ print; } /<!--#include file="[^"]+"/ { match($0, "file=\"[^\"]+\""); system("cat " substr($0, RSTART + 6, RLENGTH - 7)); }' > ${ssihtml}
+
diff --git a/sca-cpp/trunk/modules/js/Makefile.am b/sca-cpp/trunk/modules/js/Makefile.am
index 2d1efea1dd..c4e68d6e31 100644
--- a/sca-cpp/trunk/modules/js/Makefile.am
+++ b/sca-cpp/trunk/modules/js/Makefile.am
@@ -18,11 +18,14 @@
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
+BUILT_SOURCES = htdocs/base.js htdocs/all.js
+htdocs/base.js: htdocs/util.js htdocs/ui.js
+ cat $^ >htdocs/base.js
+
htdocs/all.js: ${jsfiles}
cat $^ >htdocs/all.js
-minified = htdocs/all-min.js htdocs/ui-min.css
+minified = htdocs/all-min.js htdocs/base-min.js htdocs/ui-min.css
SUFFIXES = -min.html -min.js -min.css
.html-min.html:
@@ -34,9 +37,9 @@ SUFFIXES = -min.html -min.js -min.css
.css-min.css:
../../modules/http/minify-css $< $@
-CLEANFILES = htdocs/all.js ${minified}
+CLEANFILES = htdocs/base.js htdocs/all.js ${minified}
-dist_mod_SCRIPTS = js-conf
+dist_mod_SCRIPTS = js-conf js-extract
moddir = $(prefix)/modules/js
nobase_dist_mod_DATA = ${minified}
EXTRA_DIST = ${jsfiles} htdocs/ui.css
diff --git a/sca-cpp/trunk/modules/js/htdocs/component.js b/sca-cpp/trunk/modules/js/htdocs/component.js
index 0a8ec5f5d5..8d3f727f54 100644
--- a/sca-cpp/trunk/modules/js/htdocs/component.js
+++ b/sca-cpp/trunk/modules/js/htdocs/component.js
@@ -15,16 +15,6 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
- *
- * The JSON-RPC client code is based on Jan-Klaas' JavaScript
- * o lait library (jsolait).
- *
- * $Id: jsonrpc.js,v 1.36.2.3 2006/03/08 15:09:37 mclark Exp $
- *
- * Copyright (c) 2003-2004 Jan-Klaas Kollhof
- * Copyright (c) 2005 Michael Clark, Metaparadigm Pte Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
*/
/**
@@ -34,72 +24,6 @@
var JSONClient = {};
/**
- * Escape a character.
- */
-JSONClient.escapeJSONChar = function(c) {
- if(c == "\"" || c == "\\") return "\\" + c;
- if(c == "\b") return "\\b";
- if(c == "\f") return "\\f";
- if(c == "\n") return "\\n";
- if(c == "\r") return "\\r";
- if(c == "\t") return "\\t";
- var hex = c.charCodeAt(0).toString(16);
- if(hex.length == 1) return "\\u000" + hex;
- if(hex.length == 2) return "\\u00" + hex;
- if(hex.length == 3) return "\\u0" + hex;
- return "\\u" + hex;
-};
-
-/**
- * Encode a string into JSON format.
- */
-JSONClient.escapeJSONString = function(s) {
- // The following should suffice but Safari's regex is broken (doesn't support callback substitutions)
- // return "\"" + s.replace(/([^\u0020-\u007f]|[\\\"])/g, JSONClient.escapeJSONChar) + "\"";
-
- // Rather inefficient way to do it
- var parts = s.split("");
- for(var i = 0; i < parts.length; i++) {
- var c = parts[i];
- if(c == '"' || c == '\\' || c.charCodeAt(0) < 32 || c.charCodeAt(0) >= 128)
- parts[i] = JSONClient.escapeJSONChar(parts[i]);
- }
- return "\"" + parts.join("") + "\"";
-};
-
-/**
- * Marshall objects to JSON format.
- */
-JSONClient.toJSON = function(o) {
- if(o == null)
- return "null";
- if(o.constructor == String)
- return JSONClient.escapeJSONString(o);
- if(o.constructor == Number)
- return o.toString();
- if(o.constructor == Boolean)
- return o.toString();
- if(o.constructor == Date)
- return '{javaClass: "java.util.Date", time: ' + o.valueOf() +'}';
- if(o.constructor == Array) {
- var v = [];
- for(var i = 0; i < o.length; i++)
- v.push(JSONClient.toJSON(o[i]));
- return "[" + v.join(", ") + "]";
- }
- var v = [];
- for(attr in o) {
- if(o[attr] == null)
- v.push("\"" + attr + "\": null");
- else if(typeof o[attr] == "function")
- ; // Skip
- else
- v.push(JSONClient.escapeJSONString(attr) + ": " + JSONClient.toJSON(o[attr]));
- }
- return "{" + v.join(", ") + "}";
-};
-
-/**
* Construct an HTTPBindingClient.
*/
function HTTPBindingClient(name, uri, domain) {
@@ -114,6 +38,17 @@ function HTTPBindingClient(name, uri, domain) {
*/
/**
+ * Run a function asynchronously.
+ */
+HTTPBindingClient.delaying = false;
+HTTPBindingClient.delay = function(f) {
+ if (HTTPBindingClient.delaying)
+ return window.setTimeout(f, 0);
+ else
+ return f();
+};
+
+/**
* Generate client proxy apply method.
*/
HTTPBindingClient.prototype.createApplyMethod = function() {
@@ -121,10 +56,10 @@ HTTPBindingClient.prototype.createApplyMethod = function() {
var methodName = arguments[0];
var args = [];
for(var i = 1; i < arguments.length; i++)
- args.push(arguments[i]);
+ args[args.length] = arguments[i];
- var cb = null;
- if(typeof args[args.length - 1] == "function")
+ var cb;
+ if(typeof args[args.length - 1] == 'function')
cb = args.pop();
var req = HTTPBindingClient.makeJSONRequest(methodName, args, cb);
@@ -151,7 +86,7 @@ HTTPBindingClient.makeJSONRequest = function(methodName, args, cb) {
obj.id = req.id;
obj.method = methodName;
obj.params = args;
- req.data = JSONClient.toJSON(obj);
+ req.data = JSON.stringify(obj);
return req;
};
@@ -159,62 +94,39 @@ HTTPBindingClient.makeJSONRequest = function(methodName, args, cb) {
* Return the JSON result from an XMLHttpRequest.
*/
HTTPBindingClient.jsonResult = function(http) {
- // Get the charset
- function httpCharset(http) {
- try {
- var contentType = http.getResponseHeader("Content-Type");
- var parts = contentType.split(/\s*;\s*/);
- for(var i = 0; i < parts.length; i++) {
- if(parts[i].substring(0, 8) == "charset=")
- return parts[i].substring(8, parts[i].length);
- }
- } catch (e) {}
- return "UTF-8";
- }
- if(!HTTPBindingClient.charset)
- HTTPBindingClient.charset = httpCharset(http);
-
- // Unmarshall the JSON response
- var obj;
- eval("obj = " + http.responseText);
- if(obj.error)
- throw new HTTPBindingClient.Exception(obj.error.code, obj.error.msg);
- var res = obj.result;
- return res;
+ var obj = JSON.parse(http.responseText);
+ return obj.result;
};
/**
* Schedule async requests, limiting the number of concurrent running requests.
*/
-HTTPBindingClient.queuedRequests = new Array();
-HTTPBindingClient.runningRequests = new Array();
-HTTPBindingClient.concurrentRequests = 2;
+HTTPBindingClient.queuedRequests = [];
+HTTPBindingClient.runningRequests = [];
+HTTPBindingClient.concurrentRequests = 4;
HTTPBindingClient.scheduleAsyncRequest = function(f, cancelable) {
- //debug('schedule async request, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length);
+ debug('component schedule async request', 'running', HTTPBindingClient.runningRequests.length, 'queued', HTTPBindingClient.queuedRequests.length);
// Queue the request function
var req = new Object();
req.f = f;
req.cancelable = cancelable;
req.canceled = false;
- HTTPBindingClient.queuedRequests.push(req);
+ HTTPBindingClient.queuedRequests[HTTPBindingClient.queuedRequests.length] = req;
// Execute any requests in the queue
- setTimeout(function() {
- HTTPBindingClient.runAsyncRequests(true);
- }, 0);
- return true;
+ return HTTPBindingClient.runAsyncRequests();
};
HTTPBindingClient.forgetRequest = function(req) {
- req.http = null;
+ req.http = undefined;
// Remove a request from the list of running requests
- for (i in HTTPBindingClient.runningRequests) {
+ for (var i in HTTPBindingClient.runningRequests) {
if (HTTPBindingClient.runningRequests[i] == req) {
HTTPBindingClient.runningRequests.splice(i, 1);
- //debug('forget async request, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length);
+ debug('forget async request', 'running', HTTPBindingClient.runningRequests.length, 'queued', HTTPBindingClient.queuedRequests.length);
return true;
}
}
@@ -222,33 +134,32 @@ HTTPBindingClient.forgetRequest = function(req) {
};
HTTPBindingClient.cancelRequests = function() {
- //debug('cancel async requests, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length);
+ debug('component cancel async requests', 'running', HTTPBindingClient.runningRequests.length, 'queued', HTTPBindingClient.queuedRequests.length);
// Cancel any cancelable in flight HTTP requests
- for (i in HTTPBindingClient.queuedRequests) {
+ for (var i in HTTPBindingClient.queuedRequests) {
var req = HTTPBindingClient.queuedRequests[i];
if (req.cancelable)
req.canceled = true;
}
- for (i in HTTPBindingClient.runningRequests) {
+ for (var i in HTTPBindingClient.runningRequests) {
var req = HTTPBindingClient.runningRequests[i];
if (req.cancelable) {
req.canceled = true;
if (req.http) {
+ req.http.aborted = true;
req.http.abort();
- req.http = null;
- //debug('abort async request, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length);
+ req.http = undefined;
+ debug('component abort async request', 'running', HTTPBindingClient.runningRequests.length, 'queued', HTTPBindingClient.queuedRequests.length);
}
}
}
// Flush the queue
- setTimeout(function() {
- HTTPBindingClient.runAsyncRequests(true);
- }, 0);
+ return HTTPBindingClient.runAsyncRequests();
}
-HTTPBindingClient.runAsyncRequests = function(fromui) {
+HTTPBindingClient.runAsyncRequests = function() {
// Stop now if we already have enough requests running or there's no request in the queue
if(HTTPBindingClient.runningRequests.length >= HTTPBindingClient.concurrentRequests || HTTPBindingClient.queuedRequests.length == 0)
return true;
@@ -256,41 +167,38 @@ HTTPBindingClient.runAsyncRequests = function(fromui) {
// Run the first request in the queue
var req = HTTPBindingClient.queuedRequests.shift();
if (!req.canceled) {
- HTTPBindingClient.runningRequests.push(req);
- //debug('run async request, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length);
- var runAsyncRequest = function() {
- if (req.canceled) {
- HTTPBindingClient.forgetRequest(req);
- //debug('canceled timed async request, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length);
- return false;
- }
+ HTTPBindingClient.runningRequests[HTTPBindingClient.runningRequests.length] = req;
+ debug('component run async request', 'running', HTTPBindingClient.runningRequests.length, 'queued', HTTPBindingClient.queuedRequests.length);
+ if (req.canceled) {
+ HTTPBindingClient.forgetRequest(req);
+ debug('component canceled timed async request', 'running', HTTPBindingClient.runningRequests.length, 'queued', HTTPBindingClient.queuedRequests.length);
+ return false;
+ }
+ HTTPBindingClient.delay(function asyncRequest() {
try {
req.http = new XMLHttpRequest();
+ req.http.aborted = false;
return req.f(req.http, function asyncRequestDone() {
// Execute any requests left in the queue
HTTPBindingClient.forgetRequest(req);
- //debug('done async request, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length);
- HTTPBindingClient.runAsyncRequests(false);
+ debug('component done async request', 'running', HTTPBindingClient.runningRequests.length, 'queued', HTTPBindingClient.queuedRequests.length);
+ HTTPBindingClient.runAsyncRequests();
return true;
});
} catch(e) {
// Execute any requests left in the queue
HTTPBindingClient.forgetRequest(req);
- //debug('err async request, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length);
- HTTPBindingClient.runAsyncRequests(false);
+ debug('component async request error', 'running', HTTPBindingClient.runningRequests.length, 'queued', HTTPBindingClient.queuedRequests.length, 'error', e);
+ HTTPBindingClient.runAsyncRequests();
}
return false;
- };
- if (false)
- setTimeout(runAsyncRequest, 0);
- else
- runAsyncRequest();
+ });
} else {
- //debug('canceled queued async request, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length);
+ debug('component canceled queued async request', 'running', HTTPBindingClient.runningRequests.length, 'queued', HTTPBindingClient.queuedRequests.length);
}
// Execute any requests left in the queue
- HTTPBindingClient.runAsyncRequests(fromui);
+ HTTPBindingClient.runAsyncRequests();
};
/**
@@ -298,24 +206,24 @@ HTTPBindingClient.runAsyncRequests = function(fromui) {
*/
HTTPBindingClient.getCacheItem = function(k) {
var ls = lstorage || localStorage;
- return ls.getItem('cache.d.' + k);
+ return ls.getItem('dc.d.' + k);
};
/**
* Set a cache item in local storage.
*/
HTTPBindingClient.setCacheItem = function(k, v) {
+ if (v && v.length > 65535)
+ return HTTPBindingClient.removeCacheItem(k);
HTTPBindingClient.collectCacheItems();
var ls = lstorage || localStorage;
- try {
- var s = ls.getItem('cache.size');
- var size = parseInt(s);
- var ov = ls.getItem('cache.d.' + k);
- var nsize = size - (ov != null? ov.length : 0) + (v != null? v.length : 0);
- if (nsize != size)
- ls.setItem('cache.size', nsize.toString());
- } catch(e) {}
- return ls.setItem('cache.d.' + k, v);
+ var s = ls.getItem('dc.size');
+ var size = s? parseInt(s) : 0;
+ var ov = ls.getItem('dc.d.' + k);
+ var nsize = size - (ov? ov.length : 0) + (v? v.length : 0);
+ if (nsize != size)
+ ls.setItem('dc.size', nsize.toString());
+ return ls.setItem('dc.d.' + k, v);
};
/**
@@ -323,16 +231,14 @@ HTTPBindingClient.setCacheItem = function(k, v) {
*/
HTTPBindingClient.removeCacheItem = function(k) {
var ls = lstorage || localStorage;
- try {
- var s = ls.getItem('cache.size');
- var size = parseInt(s);
- var ov = ls.getItem('cache.d' + k);
- if (ov != null) {
- var nsize = size - ov.length;
- ls.setItem('cache.size', nsize.toString());
- }
- } catch(e) {}
- return ls.removeItem('cache.d.' + k);
+ var s = ls.getItem('dc.size');
+ var size = s? parseInt(s) : 0;
+ var ov = ls.getItem('dc.d.' + k);
+ if (ov) {
+ var nsize = size - ov.length;
+ ls.setItem('dc.size', nsize.toString());
+ }
+ return ls.removeItem('dc.d.' + k);
};
/**
@@ -343,61 +249,59 @@ HTTPBindingClient.collectCacheSize = /* 10000; */ 1048576;
HTTPBindingClient.collectCacheItems = function() {
var ls = window.lstorage || localStorage;
var nkeys = window.lstorage? function() { return ls.length(); } : function() { return ls.length; };
- try {
- // Get the current cache size
- var size = 0;
- var s = ls.getItem('cache.size');
- if(s == null) {
- // Calculate and store initial cache size
- //debug('calculating cache size');
- var n = nkeys();
- for(var i = 0; i < n; i++) {
- var k = ls.key(i);
- if(k == null || k.substr(0, 8) != 'cache.d.')
- continue;
- var v = ls.getItem(k);
- if(v == null)
- continue;
- size += v.length;
- }
- ls.setItem('cache.size', size.toString());
- } else
- size = parseInt(s);
-
- // Nothing to do if it's below the max size
- //debug('cache.size', size);
- if (size <= HTTPBindingClient.maxCacheSize)
- return false;
- // Collect random cache entries until we reach our min size
- //debug('collecting cache items');
- var keys = new Array();
+ // Get the current cache size
+ var size = 0;
+ var s = ls.getItem('dc.size');
+ if(!s) {
+ // Calculate and store initial cache size
+ debug('component calculating cache size');
var n = nkeys();
for(var i = 0; i < n; i++) {
var k = ls.key(i);
- if(k == null || k.substr(0, 8) != 'cache.d.')
- continue;
- keys.push(k);
- }
- while (keys.length != 0 && size >= HTTPBindingClient.collectCacheSize) {
- var r = Math.floor(keys.length * Math.random());
- if (r == keys.length)
+ if(!k || k.substr(0, 5) != 'dc.d.')
continue;
- var k = keys[r];
var v = ls.getItem(k);
- //debug('collect cache item', k);
- ls.removeItem(k);
- keys.splice(r, 1);
- if (v != null)
- size = size - v.length;
+ if(!v)
+ continue;
+ size += v.length;
}
+ ls.setItem('dc.size', size.toString());
+ } else
+ size = parseInt(s);
+
+ // Nothing to do if it's below the max size
+ debug('component cache size', size);
+ if (size <= HTTPBindingClient.maxCacheSize)
+ return false;
+
+ // Collect random cache entries until we reach our min size
+ debug('component collecting cache items');
+ var keys = [];
+ var n = nkeys();
+ for(var i = 0; i < n; i++) {
+ var k = ls.key(i);
+ if(!k || k.substr(0, 5) != 'dc.d.')
+ continue;
+ keys[keys.length] = k;
+ }
+ while (keys.length != 0 && size >= HTTPBindingClient.collectCacheSize) {
+ var r = Math.floor(keys.length * Math.random());
+ if (r == keys.length)
+ continue;
+ var k = keys[r];
+ var v = ls.getItem(k);
+ debug('component collect cache item', k);
+ ls.removeItem(k);
+ keys.splice(r, 1);
+ if (v)
+ size = size - v.length;
+ }
- // Store the new cache size
- //debug('updated cache.size', size);
- ls.setItem('cache.size', size.toString());
- return true;
- } catch(e) {}
- return false;
+ // Store the new cache size
+ debug('component updated cache size', size);
+ ls.setItem('dc.size', size.toString());
+ return true;
};
/**
@@ -410,28 +314,19 @@ HTTPBindingClient.prototype.jsonApply = function(req) {
if(hascb) {
var u = this.uri;
return HTTPBindingClient.scheduleAsyncRequest(function jsonApplyRequest(http, done) {
- http.open("POST", u, true);
- http.setRequestHeader("Accept", "*/*");
- http.setRequestHeader("Content-Type", "application/json-rpc");
+ http.open('POST', u, true);
+ http.setRequestHeader('Accept', '*/*');
+ http.setRequestHeader('Content-Type', 'application/json-rpc');
+ http.setRequestHeader('X-Cache-Control', 'no-cache');
http.onreadystatechange = function() {
if(http.readyState == 4) {
// Pass the result or exception
if(http.status == 200) {
- var res = null;
- try {
- res = HTTPBindingClient.jsonResult(http);
- try {
- req.cb(res);
- } catch(cbe) {}
- } catch(e) {
- try {
- req.cb(null, e);
- } catch(cbe) {}
- }
- } else {
- try {
- req.cb(null, HTTPBindingClient.Exception(http.status, http.statusText));
- } catch(cbe) {}
+ var res = HTTPBindingClient.jsonResult(http);
+ req.cb(res);
+ } if(!http.aborted) {
+ error('jsonApply error', 'status', http.status, http.statusText);
+ req.cb(undefined, new Error('' + http.status + ' ' + http.statusText));
}
return done();
}
@@ -445,13 +340,15 @@ HTTPBindingClient.prototype.jsonApply = function(req) {
// Call synchronously and return the result or exception
var http = new XMLHttpRequest();
- http.open("POST", this.uri, false);
- http.setRequestHeader("Accept", "*/*");
- http.setRequestHeader("Content-Type", "application/json-rpc");
+ http.open('POST', this.uri, false);
+ http.setRequestHeader('Accept', '*/*');
+ http.setRequestHeader('Content-Type', 'application/json-rpc');
+ http.setRequestHeader('X-Cache-Control', 'no-cache');
http.send(req.data);
if(http.status == 200)
return HTTPBindingClient.jsonResult(http);
- throw new HTTPBindingClient.Exception(http.status, http.statusText);
+ error('jsonApply error', 'status', http.status, http.statusText);
+ throw new Error('' + http.status + ' ' + http.statusText);
};
@@ -463,69 +360,64 @@ HTTPBindingClient.prototype.get = function(id, cb, mode) {
var hascb = cb? true : false;
// Get from local storage first
- var item = null;
+ var item;
if(mode != 'remote') {
item = HTTPBindingClient.getCacheItem(u);
- if(item != null && item != '') {
+ if(item && item != '') {
if(!hascb)
return item;
// Pass local result to callback
- setTimeout(function() {
- cb(item);
- }, 0);
+ cb(item);
}
}
// Call asynchronously with a callback
if(hascb) {
return HTTPBindingClient.scheduleAsyncRequest(function getRequest(http, done) {
- http.open("GET", u, true);
- http.setRequestHeader("Accept", "*/*");
+ http.open('GET', u, true);
+ http.setRequestHeader('Accept', '*/*');
+ http.setRequestHeader('X-Cache-Control', 'no-cache');
http.onreadystatechange = function() {
- //debug('readystate', http.readyState, 'status', http.status, 'headers', http.getAllResponseHeaders());
if(http.readyState == 4) {
+
// Pass result if different from local result
+ //debug('readystate', http.readyState, 'status', http.status, 'headers', http.getAllResponseHeaders());
if(http.status == 200) {
- var xl = http.getResponseHeader("X-Login");
- var ct = http.getResponseHeader("Content-Type");
- if(xl != null && xl != '' && ct != null && ct.indexOf('text/html') == 0) {
- // Detect redirect to a login page
- try {
- var le = new HTTPBindingClient.Exception(403, 'X-Login');
- if(window.onloginredirect)
- window.onloginredirect(le);
- cb(null, le);
- return done();
- } catch(cbe) {}
+ var ct = http.getResponseHeader('Content-Type');
+ if(http.responseText == '' || !ct || ct == '') {
- }
- if(http.responseText == '' || ct == null || ct == '') {
// Report empty response
- try {
- cb(null, new HTTPBindingClient.Exception(403, 'No-Content'));
- return done();
- } catch(cbe) {}
-
- } else {
- if(item == null || http.responseText != item) {
- // Store retrieved entry in local storage
- if(http.responseText != null)
- HTTPBindingClient.setCacheItem(u, http.responseText);
- try {
- cb(http.responseText);
- return done();
- } catch(cbe) {}
- }
+ error('get received empty response', 'url', u);
+ cb(undefined, new Error('500 No-Content'));
+ return done();
+
+ } else if(!item || http.responseText != item) {
+
+ // Store retrieved entry in local storage
+ //debug('received response', 'url', u, 'response', http.responseText);
+ if(http.responseText != null)
+ HTTPBindingClient.setCacheItem(u, http.responseText);
+ cb(http.responseText);
+ return done();
}
- }
- else {
+ } else if (http.status == 403) {
+
+ // Redirect to login page
+ error('get received 403 response', 'url', u);
+ var le = new Error('' + http.status + ' ' + http.statusText);
+ if(window.onloginredirect)
+ window.onloginredirect(le);
+ cb(undefined, le);
+ return done();
+
+ } else if(!http.aborted) {
+
// Pass exception if we didn't have a local result
- if(item == null) {
- try {
- cb(null, new HTTPBindingClient.Exception(http.status, http.statusText));
- return done();
- } catch(cbe) {}
+ error('get received error', 'url', u, 'status', http.status, http.statusText);
+ if(!item) {
+ cb(undefined, new Error('' + http.status + ' ' + http.statusText));
+ return done();
}
}
return done();
@@ -540,28 +432,29 @@ HTTPBindingClient.prototype.get = function(id, cb, mode) {
// Call synchronously and return the result or exception
var http = new XMLHttpRequest();
- http.open("GET", u, false);
- http.setRequestHeader("Accept", "*/*");
+ http.open('GET', u, false);
+ http.setRequestHeader('Accept', '*/*');
+ http.setRequestHeader('X-Cache-Control', 'no-cache');
http.send(null);
if(http.status == 200) {
- var xl = http.getResponseHeader("X-Login");
- var ct = http.getResponseHeader("Content-Type");
- if(xl != null && xl != '' && ct != null && ct.indexOf('text/html') == 0) {
- // Detect redirect to a login page
- var le = new HTTPBindingClient.Exception(403, 'X-Login');
- if(window.onloginredirect)
- window.onloginredirect(le);
- throw le;
-
- }
- var ct = http.getResponseHeader("Content-Type");
- if(http.responseText == '' || ct == null || ct == '') {
+ var ct = http.getResponseHeader('Content-Type');
+ if(http.responseText == '' || !ct || ct == '') {
// Report empty response
- throw new HTTPBindingClient.Exception(403, 'No-Content');
+ error('get received empty response', 'url', u);
+ throw new Error('500 No Content');
}
return http.responseText;
}
- throw new HTTPBindingClient.Exception(http.status, http.statusText);
+ if(http.status == 403) {
+ // Redirect to login page
+ error('get received 403 response', 'url', u);
+ var le = new Error('' + http.status + ' ' + http.statusText);
+ if(window.onloginredirect)
+ window.onloginredirect(le);
+ throw le;
+ }
+ error('get received error', 'url', u, 'status', http.status, http.statusText);
+ throw new Error('' + http.status + ' ' + http.statusText);
};
/**
@@ -574,22 +467,20 @@ HTTPBindingClient.prototype.post = function (entry, cb) {
if(hascb) {
var u = this.uri;
return HTTPBindingClient.scheduleAsyncRequest(function postRequest(http, done) {
- http.open("POST", u, true);
- http.setRequestHeader("Accept", "*/*");
- http.setRequestHeader("Content-Type", "application/atom+xml");
+ http.open('POST', u, true);
+ http.setRequestHeader('Accept', '*/*');
+ http.setRequestHeader('Content-Type', 'application/atom+xml');
+ http.setRequestHeader('X-Cache-Control', 'no-cache');
http.onreadystatechange = function() {
if(http.readyState == 4) {
if(http.status == 201) {
+
// Successful result
- try {
- cb(http.responseText);
- } catch(cbe) {}
+ cb(http.responseText);
}
else {
// Report status code as an exception
- try {
- cb(null, new HTTPBindingClient.Exception(http.status, http.statusText));
- } catch(cbe) {}
+ cb(undefined, new Error('' + http.status + ' ' + http.statusText));
}
return done();
}
@@ -603,15 +494,16 @@ HTTPBindingClient.prototype.post = function (entry, cb) {
// Call synchronously
var http = new XMLHttpRequest();
var hascb = cb? true : false;
- http.open("POST", this.uri, false);
- http.setRequestHeader("Accept", "*/*");
- http.setRequestHeader("Content-Type", "application/atom+xml");
+ http.open('POST', this.uri, false);
+ http.setRequestHeader('Accept', '*/*');
+ http.setRequestHeader('Content-Type', 'application/atom+xml');
+ http.setRequestHeader('X-Cache-Control', 'no-cache');
http.send(entry);
if(http.status == 201)
return http.responseText;
// Return status code as an exception
- throw new HTTPBindingClient.Exception(http.status, http.statusText);
+ throw new Error('' + http.status + ' ' + http.statusText);
};
/**
@@ -622,7 +514,7 @@ HTTPBindingClient.prototype.put = function(id, entry, cb, mode) {
var hascb = cb? true : false;
// Update local storage
- var oentry = null;
+ var oentry;
if(mode != 'remote') {
oentry = HTTPBindingClient.getCacheItem(u);
HTTPBindingClient.setCacheItem(u, entry);
@@ -631,33 +523,31 @@ HTTPBindingClient.prototype.put = function(id, entry, cb, mode) {
// Call asynchronously with a callback
if(hascb) {
return HTTPBindingClient.scheduleAsyncRequest(function putRequest(http, done) {
- http.open("PUT", u, true);
- http.setRequestHeader("Accept", "*/*");
- http.setRequestHeader("Content-Type", "application/atom+xml");
+ http.open('PUT', u, true);
+ http.setRequestHeader('Accept', '*/*');
+ http.setRequestHeader('Content-Type', 'application/atom+xml');
+ http.setRequestHeader('X-Cache-Control', 'no-cache');
http.onreadystatechange = function() {
if(http.readyState == 4) {
if(http.status == 200) {
+
// Successful result
- try {
- cb();
- } catch(cbe) {}
+ cb();
+
} else {
if(http.status == 404) {
+
// Undo local storage update
if(mode != 'remote') {
- try {
- if(oentry != null)
- HTTPBindingClient.setCacheItem(u, oentry);
- else
- HTTPBindingClient.removeCacheItem(u);
- } catch(e) {}
+ if(oentry)
+ HTTPBindingClient.setCacheItem(u, oentry);
+ else
+ HTTPBindingClient.removeCacheItem(u);
}
}
// Report status code as an exception
- try {
- cb(new HTTPBindingClient.Exception(http.status, http.statusText));
- } catch(cbe) {}
+ cb(new Error('' + http.status + ' ' + http.statusText));
}
return done();
}
@@ -671,26 +561,25 @@ HTTPBindingClient.prototype.put = function(id, entry, cb, mode) {
// Call synchronously
var http = new XMLHttpRequest();
- http.open("PUT", u, false);
- http.setRequestHeader("Accept", "*/*");
- http.setRequestHeader("Content-Type", "application/atom+xml");
+ http.open('PUT', u, false);
+ http.setRequestHeader('Accept', '*/*');
+ http.setRequestHeader('Content-Type', 'application/atom+xml');
+ http.setRequestHeader('X-Cache-Control', 'no-cache');
http.send(entry);
if(http.status == 200)
return true;
if(http.status == 404) {
// Undo local storage update
if(mode != 'remote') {
- try {
- if(oentry != null)
- HTTPBindingClient.setCacheItem(u, oentry);
- else
- HTTPBindingClient.removeCacheItem(u);
- } catch(e) {}
+ if(oentry)
+ HTTPBindingClient.setCacheItem(u, oentry);
+ else
+ HTTPBindingClient.removeCacheItem(u);
}
}
// Return status code as an exception
- throw new HTTPBindingClient.Exception(http.status, http.statusText);
+ throw new Error('' + http.status + ' ' + http.statusText);
};
/**
@@ -708,21 +597,19 @@ HTTPBindingClient.prototype.del = function(id, cb, mode) {
// Call asynchronously with a callback
if(hascb) {
return HTTPBindingClient.scheduleAsyncRequest(function delRequest(http, done) {
- http.open("DELETE", u, true);
- http.setRequestHeader("Accept", "*/*");
+ http.open('DELETE', u, true);
+ http.setRequestHeader('Accept', '*/*');
+ http.setRequestHeader('X-Cache-Control', 'no-cache');
http.onreadystatechange = function() {
if(http.readyState == 4) {
if(http.status == 200) {
+
// Successful result
- try {
- cb();
- } catch(cbe) {}
+ cb();
}
else {
// Report status code as an exception
- try {
- cb(new HTTPBindingClient.Exception(http.status, http.statusText));
- } catch(cbe) {}
+ cb(new Error('' + http.status + ' ' + http.statusText));
}
return done();
}
@@ -736,29 +623,15 @@ HTTPBindingClient.prototype.del = function(id, cb, mode) {
// Call synchronously
var http = new XMLHttpRequest();
- http.open("DELETE", u, false);
- http.setRequestHeader("Accept", "*/*");
+ http.open('DELETE', u, false);
+ http.setRequestHeader('Accept', '*/*');
+ http.setRequestHeader('X-Cache-Control', 'no-cache');
http.send(null);
if(http.status == 200)
return true;
// Report status code as an exception
- throw new HTTPBindingClient.Exception(http.status, http.statusText);
-};
-
-/**
- * HTTPBindingClient exceptions.
- */
-HTTPBindingClient.Exception = function(code, message) {
- this.name = "HTTPBindingClientException";
- this.code = code;
- this.message = message;
-};
-
-HTTPBindingClient.Exception.prototype = new Error();
-
-HTTPBindingClient.Exception.prototype.toString = function() {
- return this.name + ": " + this.message;
+ throw new Error('' + http.status + ' ' + http.statusText);
};
/**
@@ -770,7 +643,7 @@ var sca = {};
/**
* Return an HTTP client proxy.
*/
-sca.httpclient = function(name, uri, domain) {
+sca.httpClient = function(name, uri, domain) {
return new HTTPBindingClient(name, uri, domain);
};
@@ -798,15 +671,15 @@ sca.reference = function(comp, rname) {
sca.defun = function(ref) {
function defapply(name) {
return function() {
- var args = new Array();
+ var args = [];
args[0] = name;
- for(i = 0, n = arguments.length; i < n; i++)
+ for(var i = 0; i < arguments.length; i++)
args[i + 1] = arguments[i];
return this.apply.apply(this, args);
};
}
- for(f = 1; f < arguments.length; f++) {
+ for(var f = 1; f < arguments.length; f++) {
var fn = arguments[f];
ref[fn]= defapply(fn);
}
diff --git a/sca-cpp/trunk/modules/js/htdocs/jsonutil.js b/sca-cpp/trunk/modules/js/htdocs/jsonutil.js
index 9960a5d82f..9a95d44d5c 100644
--- a/sca-cpp/trunk/modules/js/htdocs/jsonutil.js
+++ b/sca-cpp/trunk/modules/js/htdocs/jsonutil.js
@@ -63,12 +63,11 @@ json.jsPropertiesToValues = function(propertiesSoFar, o, i) {
var v = json.jsValToValue(jsv);
if (typeof p == 'string') {
- var n = '' + p;
- if (n.slice(0, 1) == '@')
- return json.jsPropertiesToValues(cons(mklist(attribute, "'" + n.slice(1), v), propertiesSoFar), o, cdr(i));
+ if (p[0] == '@')
+ return json.jsPropertiesToValues(cons(mklist(attribute, "'" + p.substring(1), v), propertiesSoFar), o, cdr(i));
if (isList(v) && !json.isJSArray(v))
- return json.jsPropertiesToValues(cons(cons(element, cons("'" + n, v)), propertiesSoFar), o, cdr(i));
- return json.jsPropertiesToValues(cons(mklist(element, "'" + n, v), propertiesSoFar), o, cdr(i));
+ return json.jsPropertiesToValues(cons(cons(element, cons("'" + p, v)), propertiesSoFar), o, cdr(i));
+ return json.jsPropertiesToValues(cons(mklist(element, "'" + p, v), propertiesSoFar), o, cdr(i));
}
return json.jsPropertiesToValues(cons(v, propertiesSoFar), o, cdr(i));
};
@@ -80,9 +79,9 @@ json.jsValToValue = function(jsv) {
if (jsv == null)
return null;
if (isList(jsv))
- return json.jsPropertiesToValues(mklist(), jsv, reverse(range(0, jsv.length)));
+ return json.jsPropertiesToValues(nil, jsv, reverse(seq(0, jsv.length)));
if (typeof jsv == 'object')
- return json.jsPropertiesToValues(mklist(), jsv, reverse(properties(jsv)));
+ return json.jsPropertiesToValues(nil, jsv, reverse(properties(jsv)));
if (typeof jsv == 'string')
return '' + jsv;
return jsv;
@@ -94,7 +93,7 @@ json.jsValToValue = function(jsv) {
json.isJSON = function(l) {
if (isNull(l))
return false;
- var s = car(l).slice(0, 1);
+ var s = car(l)[0];
return s == "[" || s == "{";
};
@@ -102,10 +101,8 @@ json.isJSON = function(l) {
* Convert a list of strings representing a JSON document to a list of values.
*/
json.readJSON = function(l) {
- var s = writeStrings(l);
- var obj;
- eval('obj = { \"val\": ' + s + " }");
- return json.jsValToValue(obj.val);
+ var v = JSON.parse(writeStrings(l));
+ return json.jsValToValue(v);
};
/**
@@ -126,7 +123,7 @@ json.valueToJSVal = function(v) {
if (!isList(v))
return v;
if (json.isJSArray(v))
- return json.valuesToJSElements(range(0, v.length), v, 0);
+ return json.valuesToJSElements(seq(0, v.length), v, 0);
return json.valuesToJSProperties({}, v);
};
@@ -139,14 +136,14 @@ json.valuesToJSProperties = function(o, l) {
var token = car(l);
if (isTaggedList(token, attribute)) {
var pv = json.valueToJSVal(attributeValue(token));
- o['@' + attributeName(token).slice(1)] = pv;
+ o['@' + attributeName(token).substring(1)] = pv;
} else if (isTaggedList(token, element)) {
if (elementHasValue(token)) {
var pv = json.valueToJSVal(elementValue(token));
- o[elementName(token).slice(1)] = pv;
+ o[elementName(token).substring(1)] = pv;
} else {
var child = {};
- o[elementName(token).slice(1)] = child;
+ o[elementName(token).substring(1)] = child;
json.valuesToJSProperties(child, elementChildren(token));
}
}
@@ -159,11 +156,10 @@ json.valuesToJSProperties = function(o, l) {
json.writeJSON = function(l) {
var jsv;
if (json.isJSArray(l))
- jsv = json.valuesToJSElements(range(0, l.length), l, 0);
+ jsv = json.valuesToJSElements(seq(0, l.length), l, 0);
else
jsv = json.valuesToJSProperties({}, l);
- var s = json.toJSON(jsv);
- return mklist(s);
+ return mklist(JSON.stringify(jsv));
}
/**
@@ -193,69 +189,3 @@ json.jsonResultValue = function(s) {
return val;
};
-/**
- * Escape a character.
- */
-json.escapeJSONChar = function(c) {
- if(c == "\"" || c == "\\") return "\\" + c;
- if (c == "\b") return "\\b";
- if (c == "\f") return "\\f";
- if (c == "\n") return "\\n";
- if (c == "\r") return "\\r";
- if (c == "\t") return "\\t";
- var hex = c.charCodeAt(0).toString(16);
- if(hex.length == 1) return "\\u000" + hex;
- if(hex.length == 2) return "\\u00" + hex;
- if(hex.length == 3) return "\\u0" + hex;
- return "\\u" + hex;
-};
-
-/**
- * Encode a string into JSON format.
- */
-json.escapeJSONString = function(s) {
- // The following should suffice but Safari's regex is broken (doesn't support callback substitutions)
- // return "\"" + s.replace(/([^\u0020-\u007f]|[\\\"])/g, json.escapeJSONChar) + "\"";
-
- // Rather inefficient way to do it
- var parts = s.split("");
- for(var i = 0; i < parts.length; i++) {
- var c = parts[i];
- if(c == '"' || c == '\\' || c.charCodeAt(0) < 32 || c.charCodeAt(0) >= 128)
- parts[i] = json.escapeJSONChar(parts[i]);
- }
- return "\"" + parts.join("") + "\"";
-};
-
-/**
- * Marshall objects to JSON format.
- */
-json.toJSON = function(o) {
- if(o == null)
- return "null";
- if(o.constructor == String)
- return json.escapeJSONString(o);
- if(o.constructor == Number)
- return o.toString();
- if(o.constructor == Boolean)
- return o.toString();
- if(o.constructor == Date)
- return '{javaClass: "java.util.Date", time: ' + o.valueOf() +'}';
- if(o.constructor == Array) {
- var v = [];
- for(var i = 0; i < o.length; i++)
- v.push(json.toJSON(o[i]));
- return "[" + v.join(", ") + "]";
- }
- var v = [];
- for(attr in o) {
- if(o[attr] == null)
- v.push("\"" + attr + "\": null");
- else if(typeof o[attr] == "function")
- ; // Skip
- else
- v.push(json.escapeJSONString(attr) + ": " + json.toJSON(o[attr]));
- }
- return "{" + v.join(", ") + "}";
-};
-
diff --git a/sca-cpp/trunk/modules/js/htdocs/ui.css b/sca-cpp/trunk/modules/js/htdocs/ui.css
index cdc9e31aef..69299eb882 100644
--- a/sca-cpp/trunk/modules/js/htdocs/ui.css
+++ b/sca-cpp/trunk/modules/js/htdocs/ui.css
@@ -21,16 +21,14 @@
* Main body.
*/
body, .body {
-margin-top: 0px; margin-bottom: 2px; margin-left: 2px; margin-right: 2px;
-font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 14px;
-background-color: #ffffff; opacity: 1;
+margin-top: 0px; margin-bottom: 2px; margin-left: 0px; margin-right: 0px;
+font-family: "Helvetica Neue", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 14px;
+cursor: default;
-webkit-font-smoothing: subpixel-antialiased;
--webkit-text-size-adjust: none;
+-webkit-text-size-adjust: none; -moz-text-size-adjust: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: rgba(0,0,0,0);
--webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;
-cursor: default;
--webkit-backface-visibility: hidden;
+-webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;
}
.delayed {
@@ -38,174 +36,63 @@ display: none;
}
.installer {
-position: relative; width: 0px; height: 0px; display: none; visibility: hidden; background: transparent;
+position: absolute; width: 0px; height: 0px; display: none; visibility: hidden;
}
.filler {
-position: relative; left: 0px; top: 0px; width: 1px; background: transparent; z-index: -20;
+position: absolute; left: 0px; top: 0px; width: 1px; z-index: -20;
}
/**
- * Main view.
+ * Views.
*/
.viewcontainer3dm {
-position: fixed; left: 0px; top: 70px; right: 0px; bottom: 25px; padding-top: 2px; padding-bottom: 2px;
--webkit-backface-visibility: hidden;
+position: absolute; left: 0px; top: 0px; right: 0px;
}
.viewcontainer3d {
-position: fixed; left: 0px; top: 70px; right: 0px; bottom: 25px; padding-top: 2px; padding-bottom: 2px;
--webkit-backface-visibility: hidden;
-}
-
-.leftviewloading3dm {
-position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
-z-index: -5; background-color: #ffffff;
--webkit-transform: translate(100%, 0px);
--moz-transform: translate(100%, 0px);
--ms-transform: translate(100%, 0px);
--o-transform: translate(100%, 0px);
-transform: translate(100%, 0px);
--webkit-backface-visibility: hidden;
-}
-
-.rightviewloading3dm {
-position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
-z-index: -5; background-color: #ffffff;
--webkit-transform: translate(-100%, 0px);
--moz-transform: translate(-100%, 0px);
--ms-transform: translate(-100%, 0px);
--o-transform: translate(-100%, 0px);
-transform: translate(-100%, 0px);
--webkit-backface-visibility: hidden;
-}
-
-.viewloading3d {
-position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
-z-index: -5; background-color: #ffffff;
--webkit-transform: translate(100%, 0px);
--moz-transform: translate(100%, 0px);
--ms-transform: translate(100%, 0px);
--o-transform: translate(100%, 0px);
-transform: translate(100%, 0px);
--webkit-backface-visibility: hidden;
-}
-
-.viewloaded3dm {
-position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
-z-index: 0; background-color: #ffffff;
--webkit-transition: -webkit-transform 0.4s ease-in-out;
--moz-transition: -moz-transform 0.4s ease-in-out;
--ms-transition: -ms-transform 0.4s ease-in-out;
--o-transition: -o-transform 0.4s ease-in-out;
-transition: transform 0.4s ease-in-out;
--webkit-transform: translate(0px, 0px);
--moz-transform: translate(0px, 0px);
--ms-transform: translate(0px, 0px);
--o-transform: translate(0px, 0px);
-transform: translate(0px, 0px);
--webkit-backface-visibility: hidden;
-}
-
-.viewloaded3d {
-position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
-z-index: 0; background-color: #ffffff;
--webkit-transform: translate(0px, 0px);
--moz-transform: translate(0px, 0px);
--ms-transform: translate(0px, 0px);
--o-transform: translate(0px, 0px);
-transform: translate(0px, 0px);
--webkit-backface-visibility: hidden;
-}
-
-.viewunloading3dm {
-position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
-z-index: -10; background-color: #ffffff;
--webkit-transform: translate(0px, 0px);
--moz-transform: translate(0px, 0px);
--ms-transform: translate(0px, 0px);
--o-transform: translate(0px, 0px);
-transform: translate(0px, 0px);
--webkit-backface-visibility: hidden;
-}
-
-.leftviewunloaded3dm {
-position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
-z-index: -10; background-color: #ffffff;
--webkit-transition: -webkit-transform 0.4s ease-in-out;
--moz-transition: -moz-transform 0.4s ease-in-out;
--ms-transition: -ms-transform 0.4s ease-in-out;
--o-transition: -o-transform 0.4s ease-in-out;
-transition: transform 0.4s ease-in-out;
--webkit-transform: translate(-100%, 0px);
--moz-transform: translate(-100%, 0px);
--ms-transform: translate(-100%, 0px);
--o-transform: translate(-100%, 0px);
-transform: translate(-100%, 0px);
--webkit-backface-visibility: hidden;
-}
-
-.rightviewunloaded3dm {
-position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
-z-index: -10; background-color: #ffffff;
--webkit-transition: -webkit-transform 0.4s ease-in-out;
--moz-transition: -moz-transform 0.4s ease-in-out;
--ms-transition: -ms-transform 0.4s ease-in-out;
--o-transition: -o-transform 0.4s ease-in-out;
-transition: transform 0.4s ease-in-out;
--webkit-transform: translate(100%, 0px);
--moz-transform: translate(100%, 0px);
--ms-transform: translate(100%, 0px);
--o-transform: translate(100%, 0px);
-transform: translate(100%, 0px);
--webkit-backface-visibility: hidden;
-}
-
-.viewunloaded3d {
-position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;
-z-index: -10; background-color: #ffffff;
--webkit-transform: translate(-100%, 0px);
--moz-transform: translate(-100%, 0px);
--ms-transform: translate(-100%, 0px);
--o-transform: translate(-100%, 0px);
-transform: translate(-100%, 0px);
--webkit-backface-visibility: hidden;
+position: absolute; left: 0px; top: 0px; right: 0px;
}
.viewcontent {
-position: absolute; left: 0px; top: 2px; right: 0px; bottom: 0px;
-overflow-x: hidden; overflow-y: scroll; -webkit-overflow-scrolling: touch;
--webkit-backface-visibility: hidden;
+position: absolute; left: 0px; top: 0px; width: 100%; padding-top: 35px; overflow: hidden;
}
.viewform {
-position: absolute; left: 0px; top: 2px; right: 0px; bottom: 0px;
-overflow-x: hidden; overflow-y: scroll; -webkit-overflow-scrolling: touch;
--webkit-backface-visibility: hidden;
-}
-
-/**
- * View header and footer.
- */
-.viewhead {
-position: fixed; left: 0px; top: 35px; height: 35px; line-height: 35px; width: 100%; z-index: 8;
-font-size: 15px; font-weight: bold; background-color: #f5f5f5; color: #000000;
-border-top: 1px; border-bottom: 1px; border-left: 0px; border-right: 0px;
-border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #e5e5e5;
--webkit-backface-visibility: hidden;
+position: absolute; left: 0px; top: 0px; width: 100%; padding-top: 35px; overflow: hidden;
}
.viewfoot {
-position: fixed; left: 0px; bottom: 0px; height: 25px; line-height: 25px; width: 100%; z-index: 8;
+position: fixed; left: 0px; bottom: 0px; height: 0px; width: 100%; z-index: 8;
font-size: 12px; background-color: #ffffff; color: #404040;
-border-top: 1px; border-bottom: 1px; border-left: 0px; border-right: 0px;
-border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #ffffff;
--webkit-backface-visibility: hidden;
+border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 0px;
+-webkit-backface-visibility: hidden; -moz-backface-visibility: hidden;
}
-.note {
-font-size: 12px; color: #808080;
-text-transform: none;
+.centeredform {
+max-width: 800px; margin: auto; padding-left: 2px; padding-right: 2px;
+}
+
+.centeredpage {
+max-width: 800px; margin: auto; padding-left: 2px; padding-right: 2px;
+}
+
+.grid100 {
+position: absolute; left: 0px; top: 0px; right: 0px; height: 460px;
+z-index: 3; overflow: hidden;
+-webkit-backface-visibility: hidden; -mozz-backface-visibility: hidden;
+}
+
+.grid320 {
+position: absolute; left: 0px; top: 0px; width: 320px; height: 460px;
+z-index: 4; overflow: hidden;
+-webkit-backface-visibility: hidden; -mozz-backface-visibility: hidden;
+}
+
+.gridfluid {
+position: absolute; left: 0px; top: 0px; height: 460px;
+z-index: 4; overflow: visible;
+-webkit-backface-visibility: hidden; -mozz-backface-visibility: hidden;
}
/**
@@ -213,47 +100,51 @@ text-transform: none;
*/
.tbarmenu {
position: fixed; top: 0px; left: 0px; z-index: 10; width: 100%; margin: 0px; padding: 0px; border-collapse: separate;
-height: 35px; line-height: 35px; background-color: #2c2c2c;
-border-top: 1px; border-bottom: 1px; border-left: 0px; border-right: 0px; border-style: solid; border-top-color: #2c2c2c; border-bottom-color: #2c2c2c;
--webkit-backface-visibility: hidden;
+height: 35px; line-height: 35px; background-color: #f5f5f5; font-size: 18px; overflow: hidden;
+border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 0px; border-style: solid; border-top-color: #f5f5f5; border-bottom-color: #f5f5f5;
+-webkit-backface-visibility: hidden; -moz-backface-visibility: hidden;
+opacity: 0.95;
}
-.tbarleft {
-padding-left: 2px; padding-right: 6px; white-space: nowrap; float: left;
-text-transform: uppercase;
+.tbartitle {
+position: absolute; top: 0px; left: 0px; width: 100%; text-align: center; z-index: 11;
}
-.tbarright {
-padding-left: 6px; padding-right: 2px; white-space: nowrap; float: right;
+.tbaritems {
+position: absolute; top: 0px; left: 0px; width: 100%; z-index: 12;
}
-.tbaramenu {
-font-size: 15px; color: #cccccc; text-decoration: none; white-space: nowrap;
+.tbarleft {
+padding-left: 6px; padding-right: 6px; float: left; display: inline-block;
}
-.tbarsmenu {
-font-size: 15px; font-weight: bold; color: #ffffff; text-decoration: none; white-space: nowrap;
+.tbarcenter {
+padding-left: 6px; padding-right: 6px; font-size: 24px!important;
+display: inline-block; max-width: 160px; overflow: hidden; text-overflow: ellipsis;
}
-.amenu {
-padding-left: 2px; padding-right: 6px; white-space: nowrap; color: #808080; text-decoration: none; float: left;
+.tbarright {
+padding-left: 6px; padding-right: 6px; float: right; display: inline-block;
+}
+
+.tbaramenu {
+color: #357ae8; text-decoration: none;
}
-.smenu {
-padding-left: 2px; padding-right: 6px; white-space: nowrap; color: #000000; text-decoration: none; float: left;
+.tbarsmenu {
+font-weight: bold; color: #357ae8; text-decoration: none;
}
-.cmenu {
-font-size: 15px; padding-left: 6px; padding-right: 6px; white-space: nowrap; color: #000000; text-decoration: none; float: left;
-padding-left: 45px;
+.tbarbluemenu {
+color: #357ae8; text-decoration: none;
}
-.bcmenu {
-font-size: 22px; padding-left: 2px; padding-right: 6px; white-space: nowrap; color: #000000; text-decoration: none;
+.tbarredmenu {
+color: #d14836; text-decoration: none;
}
-.rmenu {
-padding-left: 2px; padding-right: 2px; white-space: nowrap; white-space: nowrap; float: right;
+.tbargreenmenu {
+color: #3d9400; text-decoration: none;
}
/**
@@ -261,74 +152,51 @@ padding-left: 2px; padding-right: 2px; white-space: nowrap; white-space: nowrap;
*/
.status3d {
position: absolute; left: 0px; bottom: 0px; height: 25px; line-height: 25px; width: 100%; z-index: 9;
-background-color: #ffffff; color: #404040;
+background-color: #f5f5f5; color: #404040;
border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 0px;
-border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #ffffff;
--webkit-transform: translate(0px, 0px);
--moz-transform: translate(0px, 0px);
--ms-transform: translate(0px, 0px);
--o-transform: translate(0px, 0px);
-transform: translate(0px, 0px);
--webkit-backface-visibility: hidden;
+border-style: solid; border-top-color: #f5f5f5; border-bottom-color: #ffffff;
+transform: translate(0px, 0px); -webkit-transform: translate(0px, 0px); -moz-transform: translate(0px, 0px); -ms-transform: translate(0px, 0px);
+-webkit-backface-visibility: hidden; -moz-backface-visibility: hidden;
+opacity: 0.95;
}
.statusout3d {
position: absolute; left: 0px; bottom: 0px; height: 25px; line-height: 25px; width: 100%; z-index: 9;
-background-color: #ffffff; color: #404040;
-border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 0px;
-border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #ffffff;
--webkit-transition: -webkit-transform 0.4s ease-in-out;
--moz-transition: -moz-transform 0.4s ease-in-out;
--ms-transition: -ms-transform 0.4s ease-in-out;
--o-transition: -o-transform 0.4s ease-in-out;
-transition: transform 0.4s ease-in-out;
--webkit-transform: translate(0px, 25px);
--moz-transform: translate(0px, 25px);
--ms-transform: translate(0px, 25px);
--o-transform: translate(0px, 25px);
-transform: translate(0px, 25px);
--webkit-backface-visibility: hidden;
+background-color: #f5f5f5; color: #404040;
+border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 0px; border-style: solid; border-top-color: #f5f5f5; border-bottom-color: #ffffff;
+transform: translate(0px, 25px); -webkit-transform: translate(0px, 25px); -moz-transform: translate(0px, 25px); -ms-transform: translate(0px, 25px);
+transition: transform 0.4s ease-in-out; -webkit-transition: -webkit-transform 0.4s ease-in-out; -moz-transition: transform 0.4s ease-in-out;
+-webkit-backface-visibility: hidden; -moz-backface-visibility: hidden;
+opacity: 0.95;
}
.status3dm {
position: absolute; left: 0px; bottom: 0px; height: 25px; line-height: 25px; width: 100%; z-index: 9;
-background-color: #ffffff; color: #404040;
-border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 0px;
-border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #ffffff;
--webkit-transform: translate(0px, 0px);
--moz-transform: translate(0px, 0px);
--ms-transform: translate(0px, 0px);
--o-transform: translate(0px, 0px);
-transform: translate(0px, 0px);
--webkit-backface-visibility: hidden;
+background-color: #f5f5f5; color: #404040;
+border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 0px; border-style: solid; border-top-color: #f5f5f5; border-bottom-color: #ffffff;
+transform: translate(0px, 0px); -webkit-transform: translate(0px, 0px); -moz-transform: translate(0px, 0px); -ms-transform: translate(0px, 0px);
+-webkit-backface-visibility: hidden; -moz-backface-visibility: hidden;
+opacity: 0.95;
}
.statusout3dm {
position: absolute; left: 0px; bottom: 0px; height: 25px; line-height: 25px; width: 100%; z-index: 9;
-background-color: #ffffff; color: #404040;
-border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 0px;
-border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #ffffff;
--webkit-transition: -webkit-transform 0.4s ease-in-out;
--moz-transition: -moz-transform 0.4s ease-in-out;
--ms-transition: -ms-transform 0.4s ease-in-out;
--o-transition: -o-transform 0.4s ease-in-out;
-transition: transform 0.4s ease-in-out;
--webkit-transform: translate(0px, 25px);
--moz-transform: translate(0px, 25px);
--ms-transform: translate(0px, 25px);
--o-transform: translate(0px, 25px);
-transform: translate(0px, 25px);
--webkit-backface-visibility: hidden;
+background-color: #f5f5f5; color: #404040;
+border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 0px; border-style: solid; border-top-color: #f5f5f5; border-bottom-color: #ffffff;
+transform: translate(0px, 25px); -webkit-transform: translate(0px, 25px); -moz-transform: translate(0px, 25px); -ms-transform: translate(0px, 25px);
+transition: transform 0.4s ease-in-out; -webkit-transition: -webkit-transform 0.4s ease-in-out; -moz-transition: transform 0.4s ease-in-out;
+-webkit-backface-visibility: hidden; -moz-backface-visibility: hidden;
+opacity: 0.95;
}
.okstatus {
-font-size: 14px; padding-left: 6px; padding-right: 6px; white-space: nowrap; text-decoration: none;
-background-color: #f5f5f5; color: #000000;
+font-size: 14px; padding-left: 6px; padding-right: 6px; text-decoration: none;
+color: #000000;
width: 100%; margin-left: auto; margin-right: auto; text-align: center; float: right;
}
.errorstatus {
-font-size: 14px; padding-left: 6px; padding-right: 6px; white-space: nowrap; text-decoration: none;
+font-size: 14px; padding-left: 6px; padding-right: 6px; text-decoration: none;
background-color: #d14836; color: #ffffff;
width: 100%; margin-left: auto; margin-right: auto; text-align: center; float: right;
}
@@ -339,71 +207,46 @@ width: 100%; margin-left: auto; margin-right: auto; text-align: center; float: r
.working {
position: fixed; z-index: 15; display: none; width: 60px; height: 60px; left: 50%; top: 50%; border-bottom-color: transparent;
margin: -50px 0 0 -50px; border: 20px solid #c0c0c0; border-right-color: transparent;
-border-radius: 50%; -webkit-border-radius: 50%; -moz-border-radius: 50%;
--webkit-box-shadow: 0 0 45px 5px #f5f5f5; -moz-box-shadow: 0 0 45px 5px #f5f5f5; -ms-box-shadow: 0 0 45px 5px #f5f5f5;
--o-box-shadow: 0 0 45px 5px #f5f5f5; box-shadow: 0 0 45px 5px #f5f5f5;
--webkit-animation: spin 1s linear infinite;
--moz-animation: spin 1s linear infinite;
--ms-animation: spin 1s linear infinite;
--o-animation: spin 1s linear infinite;
-animation: spin 1s linear infinite;
-}
-
-@-webkit-keyframes spin {
-from { -webkit-transform: rotate(0deg); opacity: 0.4; }
-50% { -webkit-transform: rotate(180deg); opacity: 1; }
-to { -webkit-transform: rotate(360deg); opacity: 0.4; }
-}
-
-@-moz-keyframes spin {
-from { -moz-transform: rotate(0deg); opacity: 0.4; }
-50% { -moz-transform: rotate(180deg); opacity: 1; }
-to { -moz-transform: rotate(360deg); opacity: 0.4; }
+border-radius: 60px; -webkit-border-radius: 60px; -moz-border-radius: 60px;
+animation: spin 0.8s linear infinite; -webkit-animation: webkit-spin 0.8s linear infinite; -moz-animation: moz-spin 0.8s linear infinite;
+-webkit-backface-visibility: hidden; -moz-backface-visibility: hidden;
}
-@-ms-keyframes spin {
-from { -ms-transform: rotate(0deg); opacity: 0.4; }
-50% { -ms-transform: rotate(180deg); opacity: 1; }
-to { -ms-transform: rotate(360deg); opacity: 0.4; }
+@keyframes spin {
+0% { transform: rotate(0deg); opacity: 0.4; }
+50% { transform: rotate(180deg); opacity: 1; }
+100% { transform: rotate(360deg); opacity: 0.4; }
}
-@-o-keyframes spin {
-from { -o-transform: rotate(0deg); opacity: 0.4; }
-50% { -o-transform: rotate(180deg); opacity: 1; }
-to { -o-transform: rotate(360deg); opacity: 0.4; }
+@-webkit-keyframes webkit-spin {
+0% { -webkit-transform: rotate(0deg); opacity: 0.4; }
+50% { -webkit-transform: rotate(180deg); opacity: 1; }
+100% { -webkit-transform: rotate(360deg); opacity: 0.4; }
}
-@keyframes spin {
-from { transform: rotate(0deg); opacity: 0.4; }
+@-moz-keyframes moz-spin {
+0% { transform: rotate(0deg); opacity: 0.4; }
50% { transform: rotate(180deg); opacity: 1; }
-to { transform: rotate(360deg); opacity: 0.4; }
+100% { transform: rotate(360deg); opacity: 0.4; }
}
-/**
- * Refreshing status animation.
- */
.refreshing {
z-index: 14; display: none; width: 10px; height: 10px; border-bottom-color: transparent; vertical-align: top;
border: 5px solid #c0c0c0; border-right-color: transparent;
-border-radius: 50%; -webkit-border-radius: 50%; -moz-border-radius: 50%;
--webkit-box-shadow: 0 0 10px 5px #f5f5f5; -moz-box-shadow: 0 0 10px 5px #f5f5f5; -ms-box-shadow: 0 0 10px 5px #f5f5f5;
--o-box-shadow: 0 0 10px 5px #f5f5f5; box-shadow: 0 0 10px 5px #f5f5f5;
--webkit-animation: spin 1s linear infinite;
--moz-animation: spin 1s linear infinite;
--ms-animation: spin 1s linear infinite;
--o-animation: spin 1s linear infinite;
-animation: spin 1s linear infinite;
+border-radius: 10px; -webkit-border-radius: 10px; -moz-border-radius: 10px;
+animation: spin 0.8s linear infinite; -webkit-animation: webkit-spin 0.8s linear infinite; -moz-animation: moz-spin 0.8s linear infinite;
+-webkit-backface-visibility: hidden; -moz-backface-visibility: hidden;
}
/**
* Scrollbars.
*/
-.flatscrollbars::-webkit-scrollbar{
+.flatscrollbars::-webkit-scrollbar {
width: 10px; height: 10px; background-color: #ffffff;
-box-shadow: inset 1px 1px 0 rgba(0,0,0,.1), inset -1px -1px 0 rgba(0,0,0,.07);
+-webkit-box-shadow: inset 1px 1px 0 rgba(0,0,0,.1), inset -1px -1px 0 rgba(0,0,0,.07);
}
-.flatscrollbars::-webkit-scrollbar:hover{
+.flatscrollbars::-webkit-scrollbar:hover {
background-color: #eeeeee;
}
@@ -412,16 +255,16 @@ background-color: #eeeeee;
background-color: #666666;
}
-.flatscrollbars::-webkit-scrollbar-thumb{
+.flatscrollbars::-webkit-scrollbar-thumb {
min-height: 0.8em; min-width: 0.8em; background-color: rgba(0, 0, 0, .2);
-box-shadow: inset 1px 1px 0 rgba(0,0,0,.1), inset -1px -1px 0 rgba(0,0,0,.07);
+-webkit-box-shadow: inset 1px 1px 0 rgba(0,0,0,.1), inset -1px -1px 0 rgba(0,0,0,.07);
}
-.flatscrollbars::-webkit-scrollbar-thumb:hover{
+.flatscrollbars::-webkit-scrollbar-thumb:hover {
background-color: #bbbbbb;
}
-.flatscrollbars::-webkit-scrollbar-thumb:active{
+.flatscrollbars::-webkit-scrollbar-thumb:active {
background-color: #888888;
}
@@ -429,129 +272,191 @@ background-color: #888888;
* Base HTML elements.
*/
.text {
-padding-top: 3px; padding-bottom: 4px; vertical-align: middle; white-space: nowrap;
+padding-top: 6px; padding-bottom: 0px; padding-left: 4px; padding-right: 4px; margin-left: 0px; margin-right: 0px; vertical-align: middle;
+line-height: 16px; min-height: 22px; min-width: 30px;
+display: inline-block;
+}
+
+.note {
+font-size: 14px; color: #808080; text-transform: none; min-width: 30px;
+}
+
+.doc {
+padding-left: 4px; padding-right: 4px; min-width: 30px;
+}
+
+.intro {
+font-size: 15px; padding-left: 4px; padding-right: 4px; color: #000000; min-width: 30px;
+}
+
+.help {
+font-size: 14px; padding-left: 4px; padding-right: 4px; color: #808080; min-width: 30px;
}
.bluetext {
-color: #4787ed;
+color: #4787ed; min-width: 30px;
}
.redtext {
-color: #d14836;
+color: #d14836; min-width: 30px;
}
.greentext {
-color: #3d9400;
+color: #3d9400; min-width: 30px;
}
h1 {
-font-size: 20px; font-weight: bold; vertical-align: middle; margin-top: 5px; margin-bottom: 5px; margin-left: 2px; margin-right: 2px; white-space: nowrap;
+font-size: 24px; font-weight: normal; vertical-align: middle; white-space: normal;
+padding-top: 0px; padding-bottom: 0px; padding-left: 4px; padding-right: 4px; margin-bottom: 6px; margin-left: 0px; margin-right: 0px;
+display: inline-block; line-height: 28px; min-height: 28px; min-width: 30px;
}
h2 {
-font-size: 18px; font-weight: bold; vertical-align: middle; margin-top: 5px; margin-bottom: 5px; margin-left: 2px; margin-right: 2px; white-space: nowrap;
-}
-
-.hw1 {
-font-size: 20px; font-weight: bold; vertical-align: middle; margin-top: 5px; margin-bottom: 5px; margin-left: 2px; margin-right: 2px; white-space: normal;
-}
-
-.hw2 {
-font-size: 18px; font-weight: bold; vertical-align: middle; margin-top: 5px; margin-bottom: 5px; margin-left: 2px; margin-right: 2px; white-space: normal;
+font-size: 20px; font-weight: normal; vertical-align: middle; white-space: normal;
+padding-top: 0px; padding-bottom: 0px; padding-left: 4px; padding-right: 4px; margin-bottom: 6px; margin-left: 0px; margin-right: 0px;
+display: inline-block; line-height: 28px; min-height: 28px; min-width: 30px;
}
.hd1 {
-font-size: 20px; font-weight: bold; white-space: nowrap; padding-top: 3px; padding-bottom: 4px; vertical-align: middle;
+font-size: 24px; font-weight: normal; vertical-align: middle; white-space: normal;
+padding-top: 0px; padding-bottom: 0px; padding-left: 4px; padding-right: 4px; margin-bottom: 6px; margin-left: 0px; margin-right: 0px;
+display: inline-block; line-height: 28px; min-height: 28px; min-width: 30px;
}
.hd2 {
-font-size: 18px; font-weight: bold; white-space: nowrap; padding-top: 3px; padding-bottom: 4px; vertical-align: middle;
+font-size: 20px; font-weight: normal; vertical-align: middle; white-space: normal;
+padding-top: 0px; padding-bottom: 0px; padding-left: 4px; padding-right: 4px; margin-bottom: 6px; margin-left: 0px; margin-right: 0px;
+display: inline-block; line-height: 28px; min-height: 28px; min-width: 30px;
+}
+
+.width100 {
+width: 312px;
}
.section {
-font-size: 15px; font-weight: bold; background-color: #f5f5f5; color: #000000; height: 30px; line-height: 30px; width: 100%; display: block;
-text-align: left; padding-top: 0px; padding-bottom: 0px; padding-left: 2px; padding-right: 2px; white-space: nowrap;
-border-top: 1px; border-bottom: 1px; border-left: 0px; border-right: 0px; border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #e5e5e5; border-left-color: #e5e5e5; border-right-color: #e5e5e5;
+font-size: 20px; font-weight: normal;
+padding-top: 0px; padding-bottom: 0px; padding-left: 4px; padding-right: 4px; margin-left: 0px; margin-right: 0px;
+border-top: 1px; border-bottom: 1px; border-left: 0px; border-right: 0px; border-style: solid; border-top-color: #d9d9d9; border-bottom-color: #d9d9d9; border-left-color: #d9d9d9; border-right-color: #d9d9d9;
+display: inline-block; line-height: 26px; min-height: 28px; min-width: 30px;
}
.link {
-padding-top: 3px; padding-bottom: 4px; vertical-align: middle; white-space: nowrap;
+padding-top: 3px; padding-bottom: 4px; vertical-align: middle;
+display: inline-block; line-height: 16px; min-height: 16px; min-width: 30px;
}
a:link {
-color: #357ae8; text-decoration: none; white-space: nowrap; cursor: pointer;
+/*color: #357ae8; text-decoration: none; cursor: pointer;*/
+color: inherit; text-decoration: none; cursor: pointer;
}
a:visited {
-color: #357ae8; text-decoration: none; white-space: nowrap; cursor: pointer;
+/*color: #357ae8; text-decoration: none; cursor: pointer;*/
+color: inherit; text-decoration: none; cursor: pointer;
}
-.label{
-font-weight: bold; padding-top: 6px;
-}
-
-.lightlabel{
-font-weight: normal; color: #808080; padding-top: 6px;
+.label {
+font-weight: normal; color: #808080;
+padding-top: 6px; padding-bottom: 2px; padding-left: 4px; padding-right: 4px; margin-left: 0px; margin-right: 0px; vertical-align: middle;
+display: inline-block; line-height: 16px; min-height: 20px; min-width: 30px;
}
input {
-font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 15px;
+font-family: "Helvetica Neue", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 16px; min-width: 30px;
+background-image: none;
vertical-align: middle;
outline: none;
--webkit-text-size-adjust: 100%;
+-webkit-text-size-adjust: 100%; -moz-text-size-adjust: 100%;
}
textarea {
-font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 15px;
+font-family: "Helvetica Neue", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 16px;
+background-image: none;
outline: none;
overflow: auto; resize: none;
}
+.entry {
+padding-left: 4px; padding-right: 4px; padding-top: 0px; padding-bottom: 0px; margin: 0px;
+}
+
+.password {
+padding-left: 4px; padding-right: 4px; padding-top: 0px; padding-bottom: 0px; margin: 0px;
+}
+
.flatentry {
-font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 15px;
-vertical-align: middle;
--webkit-appearance: none; appearance: none;
+font-family: "Helvetica Neue", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 16px; vertical-align: middle;
+height: 28px; width: 100%;
+-webkit-appearance: none; -moz-appearance: none!important;
+box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box;
border: 1px solid #d9d9d9!important; border-top: 1px solid silver!important;
-box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box;
-border-radius: 1px; -webkit-border-radius: 1px; -moz-border-radius: 1px;
-margin: 1px!important; padding: 3px 1px 3px 3px;
+border-radius: 3px; -webkit-border-radius: 3px; -moz-border-radius: 3px;
+margin: 1px!important; padding: 3px 3px 3px 3px;
+}
+
+.flattextarea {
+font-family: "Helvetica Neue", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 16px; vertical-align: middle;
+width: 100%;
+-webkit-appearance: none; -moz-appearance: none!important;
+box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box;
+border: 1px solid #d9d9d9!important; border-top: 1px solid silver!important;
+border-radius: 3px; -webkit-border-radius: 3px; -moz-border-radius: 3px;
+margin: 1px!important; padding: 3px 3px 3px 3px;
+}
+
+.ifiller {
+-webkit-appearance: none; -moz-appearance: none;
+border: 0px; margin: 0px; padding: 0px;
+overflow: hidden; width: 100%; height: 0px;
}
.readentry {
-font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 15px;
-vertical-align: middle; color: #808080;
--webkit-appearance: none; appearance: none;
-border: 0px;
-box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box;
-border-radius: 1px; -webkit-border-radius: 1px; -moz-border-radius: 1px;
-margin: 1px!important; padding: 3px 1px 3px 3px;
+font-family: "Helvetica Neue", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 16px; vertical-align: middle;
+height: 28px; width: 100%;
+-webkit-appearance: none; -moz-appearance: none;
+box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box;
+border: 1px solid #ffffff!important; border-top: 1px solid ffffff!important;
+border-radius: 3px; -webkit-border-radius: 3px; -moz-border-radius: 3px;
+margin: 1px!important; padding: 3px 3px 3px 3px;
overflow: hidden; text-overflow: ellipsis;
}
+.readtextarea {
+font-family: "Helvetica Neue", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 16px; vertical-align: middle;
+width: 100%;
+-webkit-appearance: none; -moz-appearance: none;
+box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box;
+border: 1px solid #ffffff!important; border-top: 1px solid ffffff!important;
+border-radius: 3px; -webkit-border-radius: 3px; -moz-border-radius: 3px;
+margin: 1px!important; padding: 3px 3px 3px 3px;
+overflow: hidden; text-overflow: ellipsis;
+}
+
+.bigentry {
+font-size: 18px!important;
+}
+
.searchentry {
-font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 15px;
-vertical-align: middle;
--webkit-appearance: searchfield; -moz-appearance: searchfield; -ms-appearance: searchfield; appearance: searchfield;
+font-family: "Helvetica Neue", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 16px; vertical-align: middle;
+height: 28px; width: 100%;
+-webkit-appearance: searchfield; -moz-appearance: searchfield;
+box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box;
border: 1px solid #d9d9d9!important; border-top: 1px solid silver!important;
-box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box;
-border-radius: 1px; -webkit-border-radius: 1px; -moz-border-radius: 1px;
-margin: 1px!important; padding: 3px 1px 3px 3px;
+border-radius: 3px; -webkit-border-radius: 3px; -moz-border-radius: 3px;
+margin: 1px!important; padding: 3px 3px 3px 3px;
}
.checkbox {
-padding-top: 3px; padding-bottom: 4px; vertical-align: middle; white-space: nowrap;
+padding-top: 3px; padding-bottom: 4px; vertical-align: middle;
}
.flatcheckbox {
}
.editablewidget {
--webkit-user-select: text; -moz-user-select: text; -ms-user-select: text; user-select: text;
-outline: none; -moz-outline-style: none;
-}
-
-.noneditablewidget {
-outline: none; -moz-outline-style: none;
+-webkit-user-select: text; -moz-user-select: text; -ms-user-select: text;
+outline: none; outline-style: none;
+display: block;
}
iframe {
@@ -559,25 +464,44 @@ border: 0px; margin: 0px; padding: 0px;
}
img {
+padding: 0px; margin: 0px; border: 0px;
+border-radius: 0px; -webkit-border-radius: 0px; -moz-border-radius: 0px;
+display: inline-block;
+}
+
+.img {
+padding: 0px; margin: 0px; border: 0px;
+max-width: 320px; max-height: 460px;
border: 0px;
+border-radius: 0px; -webkit-border-radius: 0px; -moz-border-radius: 0px;
+background-repeat: no-repeat; float: left;
+display: inline-block;
+}
+
+.thumbnail {
+padding: 0px; margin: 0px; border: 0px;
+max-width: 50x; max-height: 50px;
+border: 0px;
+border-radius: 6px; -webkit-border-radius: 6px; -moz-border-radius: 6px;
+background-repeat: no-repeat; float: left;
+display: inline-block;
}
/**
* Tables.
*/
table {
-border: 0px; border-collapse: collapse; border-color: #a2bae7; border-style: solid;
-font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 14px;
+border: 0px; border-collapse: collapse; border-color: #f5f5f5; border-style: solid;
+font-family: "Helvetica Neue", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 14px;
}
.table {
-width: 100%;
}
th {
-font-size: 15px; font-weight: bold; background-color: #f5f5f5; color: #000000;
-text-align: left; padding-left: 2px; padding-right: 8px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; white-space: nowrap;
-border-top: 1px; border-bottom: 1px; border-left: 1px; border-right: 1px; border-style: solid; border-top-color: #e5e5e5; border-bottom-color: #e5e5e5; border-left-color: #e5e5e5; border-right-color: #e5e5e5;
+font-size: 18px; font-weight: normal; background-color: #ffffff; color: #000000;
+padding-left: 2px; padding-right: 8px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle;
+border-top: 1px; border-bottom: 1px; border-left: 1px; border-right: 1px; border-style: solid; border-top-color: #f5f5f5; border-bottom-color: #f5f5f5; border-left-color: #f5f5f5; border-right-color: #f5f5f5;
}
.thl {
@@ -593,7 +517,7 @@ padding: 0px;
}
td {
-padding-left: 2px; padding-top: 2px; padding-right: 8px; white-space: nowrap; vertical-align: middle; border: 0px;
+padding-left: 2px; padding-top: 2px; padding-right: 8px; vertical-align: middle; border: 0px;
}
.tdl {
@@ -609,33 +533,30 @@ padding-left: 2px; padding-top: 2px; padding-right: 8px; white-space: normal; ve
}
.datatd {
-border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; width: 10px; vertical-align: middle;
+border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #f5f5f5; width: 10px; vertical-align: middle;
}
.datatdl {
-border-right: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; width: 10px; vertical-align: middle;
+border-right: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #f5f5f5; width: 10px; vertical-align: middle;
}
.datatdltop {
-border-right: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; width: 10px; vertical-align: top;
+border-right: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #f5f5f5; width: 10px; vertical-align: top;
}
.datatdr {
-border-left: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; vertical-align: middle;
+border-left: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #f5f5f5; vertical-align: middle;
}
.list {
-width: 100%;
}
.datatable {
-border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; width: 100%;
+border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #f5f5f5;
}
.databg {
-opacity: .6;
--ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
-filter: alpha(opacity=60);
+opacity: 0.95;
}
/**
@@ -643,416 +564,65 @@ filter: alpha(opacity=60);
*/
button {
vertical-align: middle;
-font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 15px;
-outline: none;
--webkit-text-size-adjust: 100%;
-}
-
-.plusminus {
-font-size: 18px; font-family: "Courier New";
+font-family: "Helvetica Neue", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 18px;
+-webkit-text-size-adjust: 100%; -moz-text-size-adjust: 100%;
}
-.graybutton {
-display: inline-block; text-align: center; color: #444; font-weight: bold; font-size: 14px; text-transform: uppercase;
-padding-top: 0px; padding-bottom: 0px; padding-left: 4px; padding-right: 4px; margin-left: 2px; margin-right: 2px;
-height: 28px; line-height: 28px; min-width: 30px;
--webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px;
-cursor: default;
-border: 1px solid gainsboro; background-color: #f5f5f5;
-background-image: -webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#f1f1f1));
-background-image: -webkit-linear-gradient(top,#f5f5f5,#f1f1f1);
-background-image: -moz-linear-gradient(top,#f5f5f5,#f1f1f1);
-background-image: -ms-linear-gradient(top,#f5f5f5,#f1f1f1);
-background-image: -o-linear-gradient(top,#f5f5f5,#f1f1f1);
-background-image: linear-gradient(top,#f5f5f5,#f1f1f1);
+button::-moz-focus-inner {
+outline: none!important; border: 0px!important;
}
-.graybutton:hover {
-border: 1px solid #c6c6c6; color: #333; text-shadow: 0 1px rgba(0, 0, 0, 0.3); background-color: #f8f8f8;
-background-image: -webkit-gradient(linear,left top,left bottom,from(#f8f8f8),to(#f1f1f1));
-background-image: -webkit-linear-gradient(top,#f8f8f8,#f1f1f1);
-background-image: -moz-linear-gradient(top,#f8f8f8,#f1f1f1);
-background-image: -ms-linear-gradient(top,#f8f8f8,#f1f1f1);
-background-image: -o-linear-gradient(top,#f8f8f8,#f1f1f1);
-background-image: linear-gradient(top,#f8f8f8,#f1f1f1);
+.submit {
+visibility: hidden; height: 0px; width: 0px; max-height: 0px; padding: 0px; margin: 0px;
}
-.graybutton:active {
--webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -ms-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
--o-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+.symbolbutton {
+text-align: center; vertical-align: middle; font-family: "Courier"; font-size: 28px!important;
+display: inline-block; min-height: 28px; min-width: 30px; padding-top: 0px;
}
-.graybutton:disabled {
-color: #c0c0c0;
+.minusbutton {
+text-align: center; vertical-align: top; font-family: "Courier"; font-size: 28px!important;
+display: inline-block; min-height: 28px; min-width: 30px; padding-top: 0px;
}
-.graybutton:hover:disabled {
-color: #c0c0c0;
+.bigbutton {
+font-size: 24px!important; padding: 10px!important; height: 50px!important;
}
-.lightbutton {
-display: inline-block; text-align: center; color: #444; font-weight: normal; font-size: 14px;
-padding-top: 0px; padding-bottom: 0px; padding-left: 4px; padding-right: 4px; margin-left: 2px; margin-right: 2px;
-height: 28px; line-height: 28px; min-width: 30px;
--webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px;
-cursor: default;
-border: 1px solid gainsboro; background-color: #f5f5f5;
-background-image: -webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#f1f1f1));
-background-image: -webkit-linear-gradient(top,#f5f5f5,#f1f1f1);
-background-image: -moz-linear-gradient(top,#f5f5f5,#f1f1f1);
-background-image: -ms-linear-gradient(top,#f5f5f5,#f1f1f1);
-background-image: -o-linear-gradient(top,#f5f5f5,#f1f1f1);
-background-image: linear-gradient(top,#f5f5f5,#f1f1f1);
-}
-
-.lightbutton:hover {
-border: 1px solid #c6c6c6; color: #333; text-shadow: 0 1px rgba(0, 0, 0, 0.3); background-color: #f8f8f8;
-background-image: -webkit-gradient(linear,left top,left bottom,from(#f8f8f8),to(#f1f1f1));
-background-image: -webkit-linear-gradient(top,#f8f8f8,#f1f1f1);
-background-image: -moz-linear-gradient(top,#f8f8f8,#f1f1f1);
-background-image: -ms-linear-gradient(top,#f8f8f8,#f1f1f1);
-background-image: -o-linear-gradient(top,#f8f8f8,#f1f1f1);
-background-image: linear-gradient(top,#f8f8f8,#f1f1f1);
-}
-
-.lightbutton:active {
--webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -ms-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
--o-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+.graybutton {
+color: #808080!important; font-size: 18px;
+padding-top: 0px; padding-bottom: 0px; padding-left: 6px; padding-right: 6px; margin-left: 0px; margin-right: 0px; text-align: center; vertical-align: top;
+display: inline-block; line-height: 28px; min-height: 28px; min-width: 30px;
}
-.lightbutton:disabled {
-color: #c0c0c0;
+.blackbutton {
+color: #000000!important; font-size: 18px;
+padding-top: 0px; padding-bottom: 0px; padding-left: 6px; padding-right: 6px; margin-left: 0px; margin-right: 0px; text-align: center; vertical-align: top;
+display: inline-block; line-height: 28px; min-height: 28px; min-width: 30px;
}
-.lightbutton:hover:disabled {
-color: #c0c0c0;
+.lightbutton {
+color: #808080!important; font-size: 18px;
+padding-top: 0px; padding-bottom: 0px; padding-left: 6px; padding-right: 6px; margin-left: 0px; margin-right: 0px; text-align: center; vertical-align: top;
+display: inline-block; line-height: 28px; min-height: 28px; min-width: 30px;
}
.bluebutton {
-display: inline-block; text-align: center; font-weight: bold; font-size: 14px; text-transform: uppercase;
-padding-top: 0px; padding-bottom: 0px; padding-left: 4px; padding-right: 4px; margin-left: 2px; margin-right: 2px;
-height: 28px; line-height: 28px; min-width: 30px;
--webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px;
-cursor: default;
-border: 1px solid #3079ed; color: #ffffff; text-shadow: 0 1px rgba(0, 0, 0, 0.1); background-color: #4d90fe;
-background-image: -webkit-gradient(linear,left top,left bottom,from(#4d90fe),to(#4787ed));
-background-image: -webkit-linear-gradient(top,#4d90fe,#4787ed);
-background-image: -moz-linear-gradient(top,#4d90fe,#4787ed);
-background-image: -ms-linear-gradient(top,#4d90fe,#4787ed);
-background-image: -o-linear-gradient(top,#4d90fe,#4787ed);
-background-image: linear-gradient(top,#4d90fe,#4787ed);
-}
-
-.bluebutton:hover {
-border: 1px solid #2f5bb7; color: #ffffff; text-shadow: 0 1px rgba(0, 0, 0, 0.3); background-color: #357ae8;
-background-image: -webkit-gradient(linear,left top,left bottom,from(#4d90fe),to(#357ae8));
-background-image: -webkit-linear-gradient(top,#4d90fe,#357ae8);
-background-image: -moz-linear-gradient(top,#4d90fe,#357ae8);
-background-image: -ms-linear-gradient(top,#4d90fe,#357ae8);
-background-image: -o-linear-gradient(top,#4d90fe,#357ae8);
-background-image: linear-gradient(top,#4d90fe,#357ae8);
-}
-
-.bluebutton:active {
--webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -ms-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
--o-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
-}
-
-.bluebutton:disabled {
-color: #c0c0c0;
-}
-
-.bluebutton:hover:disabled {
-color: #c0c0c0;
+color: #4d90fe!important; font-size: 18px;
+padding-top: 0px; padding-bottom: 0px; padding-left: 6px; padding-right: 6px; margin-left: 0px; margin-right: 0px; text-align: center; vertical-align: top;
+display: inline-block; line-height: 28px; min-height: 28px; min-width: 30px;
}
.greenbutton {
-display: inline-block; text-align: center; font-weight: bold; font-size: 14px; text-transform: uppercase;
-padding-top: 0px; padding-bottom: 0px; padding-left: 4px; padding-right: 4px; margin-left: 2px; margin-right: 2px;
-height: 28px; line-height: 28px; min-width: 30px;
--webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px;
-cursor: default;
-border: 1px solid #29691d; color: #ffffff; text-shadow: 0 1px rgba(0, 0, 0, 0.1); background-color: #3d9400;
-background-image: -webkit-gradient(linear,left top,left bottom,from(#3d9400),to(#398a00));
-background-image: -webkit-linear-gradient(top,#3d9400,#398a00);
-background-image: -moz-linear-gradient(top,#3d9400,#398a00);
-background-image: -ms-linear-gradient(top,#3d9400,#398a00);
-background-image: -o-linear-gradient(top,#3d9400,#398a00);
-background-image: linear-gradient(top,#3d9400,#398a00);
-}
-
-.greenbutton:hover {
-border: 1px solid #2d6200; color: #ffffff; text-shadow: 0 1px rgba(0, 0, 0, 0.3); background-color: #097b24;
-background-image: -webkit-gradient(linear,left top,left bottom,from(#3d9400),to(#097b24));
-background-image: -webkit-linear-gradient(top,#3d9400,#097b24);
-background-image: -moz-linear-gradient(top,#3d9400,#097b24);
-background-image: -ms-linear-gradient(top,#3d9400,#097b24);
-background-image: -o-linear-gradient(top,#3d9400,#097b24);
-background-image: linear-gradient(top,#3d9400,#097b24);
-}
-
-.greenbutton:active {
--webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -ms-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
--o-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
-}
-
-.greenbutton:disabled {
-color: #c0c0c0;
-}
-
-.greenbutton:hover:disabled {
-color: #c0c0c0;
+color: #3d9400!important; font-size: 18px;
+padding-top: 0px; padding-bottom: 0px; padding-left: 6px; padding-right: 6px; margin-left: 0px; margin-right: 0px; text-align: center; vertical-align: top;
+display: inline-block; line-height: 28px; min-height: 28px; min-width: 30px;
}
.redbutton {
-display: inline-block; text-align: center; font-weight: bold; font-size: 14px; text-transform: uppercase;
-padding-top: 0px; padding-bottom: 0px; padding-left: 4px; padding-right: 4px; margin-left: 2px; margin-right: 2px;
-height: 28px; line-height: 28px; min-width: 30px;
--webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px;
-cursor: default;
-border: 1px solid transparent; color: #ffffff; text-shadow: 0 1px rgba(0, 0, 0, 0.1); background-color: #d14836;
-background-image: -webkit-gradient(linear,left top,left bottom,from(#dd4b39),to(#d14836));
-background-image: -webkit-linear-gradient(top,#dd4b39,#d14836);
-background-image: -moz-linear-gradient(top,#dd4b39,#d14836);
-background-image: -ms-linear-gradient(top,#dd4b39,#d14836);
-background-image: -o-linear-gradient(top,#dd4b39,#d14836);
-background-image: linear-gradient(top,#dd4b39,#d14836);
-}
-
-.redbutton:hover {
-border: 1px solid #b0281a; border-bottom-color: #af301f; color: #ffffff; text-shadow: 0 1px rgba(0, 0, 0, 0.3); background-color: #c53727;
-background-image: -webkit-gradient(linear,left top,left bottom,from(#dd4b39),to(#c53727));
-background-image: -webkit-linear-gradient(top,#dd4b39,#c53727);
-background-image: -moz-linear-gradient(top,#dd4b39,#c53727);
-background-image: -ms-linear-gradient(top,#dd4b39,#c53727);
-background-image: -o-linear-gradient(top,#dd4b39,#c53727);
-background-image: linear-gradient(top,#dd4b39,#c53727);
-}
-
-.redbutton:active {
--webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -ms-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
--o-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
-}
-
-.redbutton:disabled {
-color: #c0c0c0;
-}
-
-.redbutton:hover:disabled {
-color: #c0c0c0;
-}
-
-/**
- * Store.
- */
-.imgbutton {
-width: 142px; height: 64px; margin-left: 20px; margin-right: 20px; padding: 0px; border: 1px; cursor: pointer;
-}
-
-.box {
-width: 148px; display: inline-block; overflow: hidden; text-overflow: ellipsis;
-border: 1px; border-style: solid; border-color: #dcdcdc; border-collapse: collapse;
-white-space: nowrap; margin: 2px; padding: 2px; vertical-align: top;
-}
-
-.appicon {
-float: left; width: 50px; vertical-align: top; padding-right: 4px; padding-top: 2px; padding-bottom: 4px;
-overflow: hidden; text-overflow: ellipsis;
-}
-
-.appdetails {
-font-size: 13px; color: #808080; overflow: hidden; text-overflow: ellipsis;
-}
-
-.apptitle {
-font-size: 14px; font-weight: bold; overflow: hidden; text-overflow: ellipsis;
-}
-
-/**
- * Editor.
- */
-.pagediv {
-position: absolute; left: 0px; top: 0px; width: 1024px; height: 1024px;
-z-index: 2; overflow: hidden;
-}
-
-.playdiv {
-position: absolute; left: 0px; top: 0px; width: 1024px; height: 1024px;
-z-index: 1; overflow: hidden;
-}
-
-.guide {
-border: 1px; border-style: solid; border-color: #fcff00;
-}
-
-.draggable3d {
-position: absolute;
--webkit-transition: -webkit-transform 0.016s linear;
--moz-transition: -moz-transform 0.016s linear;
--ms-transition: -ms-transform 0.016s linear;
--o-transition: -o-transform 0.016s linear;
-transition: transform 0.016s linear;
--webkit-backface-visibility: hidden;
-}
-
-.draggable3dm {
-position: absolute;
--webkit-transition: -webkit-transform 0.016s linear;
--moz-transition: -moz-transform 0.016s linear;
--ms-transition: -ms-transform 0.016s linear;
--o-transition: -o-transform 0.016s linear;
-transition: transform 0.016s linear;
--webkit-backface-visibility: hidden;
-}
-
-/**
- * Palette.
- */
-.palettecontainer3dm {
-position: absolute; left: 0px; top: 0px; width: 0px; bottom: 0px; padding-top: 2px; padding-bottom: 2px;
--webkit-backface-visibility: hidden;
-}
-
-.palettecontainer3d {
-position: absolute; left: 0px; top: 0px; width: 0px; bottom: 0px; padding-top: 2px; padding-bottom: 2px;
--webkit-backface-visibility: hidden;
-}
-
-.paletteloading3d {
-position: absolute; left: 0px; top: 0px; bottom: 0px;
-z-index: 6; background-color: #ffffff;
--webkit-transform: translate(-150px, 0px);
--moz-transform: translate(-150px, 0px);
--ms-transform: translate(-150px, 0px);
--o-transform: translate(-150px, 0px);
-transform: translate(-150px, 0px);
--webkit-backface-visibility: hidden;
-}
-
-.paletteloading3dm {
-position: absolute; left: 0px; top: 0px; bottom: 0px;
-z-index: 6; background-color: #ffffff;
--webkit-transform: translate(-150px, 0px);
--moz-transform: translate(-150px, 0px);
--ms-transform: translate(-150px, 0px);
--o-transform: translate(-150px, 0px);
-transform: translate(-150px, 0px);
--webkit-backface-visibility: hidden;
-}
-
-.paletteloaded3d {
-position: absolute; left: 0px; top: 0px; bottom: 0px;
-z-index: 6; background-color: #ffffff;
--webkit-transform: translate(0px, 0px);
--moz-transform: translate(0px, 0px);
--ms-transform: translate(0px, 0px);
--o-transform: translate(0px, 0px);
-transform: translate(0px, 0px);
--webkit-backface-visibility: hidden;
-}
-
-.paletteloaded3dm {
-position: absolute; left: 0px; top: 0px; bottom: 0px;
-z-index: 6; background-color: #ffffff;
--webkit-transition: -webkit-transform 0.4s ease-in-out;
--moz-transition: -moz-transform 0.4s ease-in-out;
--ms-transition: -ms-transform 0.4s ease-in-out;
--o-transition: -o-transform 0.4s ease-in-out;
-transition: transform 0.4s ease-in-out;
--webkit-transform: translate(0px, 0px);
--moz-transform: translate(0px, 0px);
--ms-transform: translate(0px, 0px);
--o-transform: translate(0px, 0px);
-transform: translate(0px, 0px);
--webkit-backface-visibility: hidden;
-}
-
-.paletteunloading3dm {
-position: absolute; left: 0px; top: 0px; bottom: 0px;
-z-index: 6; background-color: #ffffff;
--webkit-transform: translate(0px, 0px);
--moz-transform: translate(0px, 0px);
--ms-transform: translate(0px, 0px);
--o-transform: translate(0px, 0px);
-transform: translate(0px, 0px);
--webkit-backface-visibility: hidden;
-}
-
-.paletteunloaded3dm {
-position: absolute; left: 0px; top: 0px; bottom: 0px;
-z-index: 6; background-color: #ffffff;
--webkit-transition: -webkit-transform 0.4s ease-in-out;
--moz-transition: -moz-transform 0.4s ease-in-out;
--ms-transition: -ms-transform 0.4s ease-in-out;
--o-transition: -o-transform 0.4s ease-in-out;
-transition: transform 0.4s ease-in-out;
--webkit-transform: translate(-150px, 0px);
--moz-transform: translate(-150px, 0px);
--ms-transform: translate(-150px, 0px);
--o-transform: translate(-150px, 0px);
-transform: translate(-150px, 0px);
--webkit-backface-visibility: hidden;
-}
-
-.paletteunloaded {
-position: absolute; left: 0px; top: 0px; bottom: 0px;
-z-index: 6; background-color: #ffffff;
--webkit-transform: translate(-150px, 0px);
--moz-transform: translate(-150px, 0px);
--ms-transform: translate(-150px, 0px);
--o-transform: translate(-150px, 0px);
-transform: translate(-150px, 0px);
--webkit-backface-visibility: hidden;
-}
-
-.palettecontent {
-position: absolute; left: 0px; top: 0px; bottom: 0px; width: 150px;
-padding-right: 4px; padding-top: 4px; padding-bottom: 6px; z-index: 6;
-border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 1px;
-background-color: #ffffff; border-style: solid; border-color: #e5e5e5;
-overflow-y: scroll; overflow-x: hidden; -webkit-overflow-scrolling: touch;
-}
-
-.palettetable {
-border-top: 1px; border-bottom: 1px; border-left: 1px; border-right: 1px; border-style: solid; border-color: #dcdcdc;
-background-color: #ffffff; width: 100%;
-}
-
-.palettetd {
-border-top: 1px; border-bottom: 1px; border-left: 1px; border-right: 1px; border-style: solid; border-color: #dcdcdc; vertical-align: middle;
-height: 25px; padding-bottom: 6px; padding-top: 4px;
-}
-
-/**
- * Graph.
- */
-.g {
-position: absolute; display: block;
--webkit-backface-visibility: hidden;
-}
-
-.path {
-position: absolute; background: transparent; display: block;
--webkit-backface-visibility: hidden;
-}
-
-.gtitle {
-position: absolute;
-margin: 4px; padding: 0px; line-height: 15px; vertical-align: middle; white-space: nowrap;
-font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 14px; cursor: default;
-background: transparent; display: block;
--webkit-text-size-adjust: none;
--webkit-touch-callout: none;
--webkit-tap-highlight-color: rgba(0,0,0,0);
--webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;
-}
-
-.graphentry {
-font-family: "Lucida Grande", Helvetica, Arial; font-style: normal; font-variant: normal; font-size: 14px;
--webkit-appearance: none; appearance: none;
-border: 1px solid #d9d9d9!important; border-top: 1px solid silver!important;
-box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box;
-border-radius: 1px; -webkit-border-radius: 1px; -moz-border-radius: 1px;
-margin: 0px; padding: 0px;
+color: #d14836!important; font-size: 18px;
+padding-top: 0px; padding-bottom: 0px; padding-left: 6px; padding-right: 6px; margin-left: 0px; margin-right: 0px; text-align: center; vertical-align: top;
+display: inline-block; line-height: 28px; min-height: 28px; min-width: 30px;
}
diff --git a/sca-cpp/trunk/modules/js/htdocs/ui.js b/sca-cpp/trunk/modules/js/htdocs/ui.js
index 2bd21f6ed4..64acf6c14f 100644
--- a/sca-cpp/trunk/modules/js/htdocs/ui.js
+++ b/sca-cpp/trunk/modules/js/htdocs/ui.js
@@ -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, onprogress, onload) {
};
/**
+ * 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, onprogress, onload, width, height) {
/**
* 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);
};
diff --git a/sca-cpp/trunk/modules/js/htdocs/util.js b/sca-cpp/trunk/modules/js/htdocs/util.js
index a8fec3994d..00ebd7a0c6 100644
--- a/sca-cpp/trunk/modules/js/htdocs/util.js
+++ b/sca-cpp/trunk/modules/js/htdocs/util.js
@@ -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;
+})();
+*/
+
diff --git a/sca-cpp/trunk/modules/js/htdocs/xmlutil.js b/sca-cpp/trunk/modules/js/htdocs/xmlutil.js
index 29240dff9c..c8878bf2af 100644
--- a/sca-cpp/trunk/modules/js/htdocs/xmlutil.js
+++ b/sca-cpp/trunk/modules/js/htdocs/xmlutil.js
@@ -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');
}
diff --git a/sca-cpp/trunk/modules/js/js-conf b/sca-cpp/trunk/modules/js/js-conf
index 72b5a60120..f3d51cecba 100755
--- a/sca-cpp/trunk/modules/js/js-conf
+++ b/sca-cpp/trunk/modules/js/js-conf
@@ -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
diff --git a/sca-cpp/trunk/modules/js/js-extract b/sca-cpp/trunk/modules/js/js-extract
new file mode 100755
index 0000000000..6b9531e4ed
--- /dev/null
+++ b/sca-cpp/trunk/modules/js/js-extract
@@ -0,0 +1,23 @@
+#!/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
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Extract <script/> sections from an HTML file
+
+awk 'BEGIN { s=0; } /<\/script>/ { s=0; } { if (s == 1) { print; } } /<script / { s=1; } /<script .*<\/script>/ { s=0; }'
+
diff --git a/sca-cpp/trunk/patches/page-speed-1.9.patch b/sca-cpp/trunk/patches/page-speed-1.9.patch
new file mode 100644
index 0000000000..997a88ee8a
--- /dev/null
+++ b/sca-cpp/trunk/patches/page-speed-1.9.patch
@@ -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"},
diff --git a/sca-cpp/trunk/ubuntu/ubuntu-install-all b/sca-cpp/trunk/ubuntu/ubuntu-install-all
index 6f5abd7694..e296af73f8 100755
--- a/sca-cpp/trunk/ubuntu/ubuntu-install-all
+++ b/sca-cpp/trunk/ubuntu/ubuntu-install-all
@@ -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 $?
diff --git a/sca-cpp/trunk/ubuntu/ubuntu-install-nothreads b/sca-cpp/trunk/ubuntu/ubuntu-install-nothreads
index effdb6417a..58f3e00a54 100755
--- a/sca-cpp/trunk/ubuntu/ubuntu-install-nothreads
+++ b/sca-cpp/trunk/ubuntu/ubuntu-install-nothreads
@@ -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 $?