summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2011-08-06 05:59:32 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2011-08-06 05:59:32 +0000
commit3b3beac5adfa1995a9a4c92fd92a881f024be08e (patch)
treed958076da28db597359af0ae27db369925e253e4
parent4b14cefc9e79850ebb18844752771c3f141c7385 (diff)
Javascript improvements: add local storage, improve caching using URI fragments instead of query strings, simplify component layout and optimize some of the Javascript functions, and add the ability to clone components.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1154447 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/account/index.html24
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/app/cache-manifest.cmf (renamed from sca-cpp/trunk/modules/edit/htdocs/app/cache-manifest.cmf.off)1
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/app/frame.html2
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/app/index.html190
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/clone/index.html34
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/create/index.html24
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/data/index.html15
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/graph/graph.js1102
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/graph/index.html138
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/index.html18
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/login/index.html10
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/logout/index.html14
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/menu.js8
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/page/index.html103
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/page/page.js166
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/public/iframe.html2
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/public/notauth.html8
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/public/notfound.html8
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/public/notyet.html8
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/public/oops.html8
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/stats/index.html33
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/store/index.html45
-rw-r--r--sca-cpp/trunk/modules/edit/log.py2
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/all-min.js131
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/component.js212
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/elemutil.js39
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/ui-min.css63
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/ui.css133
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/ui.js172
-rw-r--r--sca-cpp/trunk/modules/js/htdocs/util.js69
30 files changed, 1775 insertions, 1007 deletions
diff --git a/sca-cpp/trunk/modules/edit/htdocs/account/index.html b/sca-cpp/trunk/modules/edit/htdocs/account/index.html
index d83ca4562b..ef1deb0527 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/account/index.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/account/index.html
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html>
+<html manifest="/cache-manifest.cmf">
<head>
<title>Account</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
@@ -28,8 +28,8 @@
<script type="text/javascript" src="/all-min.js"></script>
<script type="text/javascript" src="/menu.js"></script>
</head>
-<body class="delayed" onload="ui.onload();">
-<div id="bodydiv" class="devicewidth">
+<body class="delayed" onload="ui.onload();" onbeforeunload="ui.onbeforeunload();">
+<div id="bodydiv" class="bodydiv">
<div id="headdiv" class="hsection">
<script type="text/javascript" src="/headconfig.js"></script>
@@ -97,13 +97,18 @@
</form>
<script type="text/javascript">
+ui.initbody();
+
// Init service references
var editWidget = sca.component("EditWidget");
var user= sca.defun(sca.reference(editWidget, "user"), "id");
var accounts = sca.reference(editWidget, "accounts");
// Get the user name
-var username = user.id()
+var username = '';
+try {
+ username = user.id()
+} catch(e) {}
// Set page titles
document.title = windowtitle(window.location.hostname) + ' - Account - ' + username;
@@ -123,6 +128,11 @@ var savedaccountentryxml = '';
*/
function getaccount(name) {
return accounts.get(name, function(doc) {
+
+ // Stop now if we didn't get an account
+ if (doc == null)
+ return false;
+
accountentry = doc != null? car(elementsToValues(atom.readATOMEntry(mklist(doc)))) : mklist("'entry", mklist("'title", ''), mklist("'id", name));
var title = cadr(assoc("'title", cdr(accountentry)));
$('userTitle').value = title;
@@ -162,8 +172,10 @@ function getaccount(name) {
function save(entryxml) {
$('saveStatus').innerHTML = 'Saving';
savedaccountentryxml = entryxml;
- accounts.put(username, savedaccountentryxml);
- $('saveStatus').innerHTML = 'Saved';
+ accounts.put(username, savedaccountentryxml, function(e) {
+ if (!e)
+ $('saveStatus').innerHTML = 'Saved';
+ });
return true;
}
diff --git a/sca-cpp/trunk/modules/edit/htdocs/app/cache-manifest.cmf.off b/sca-cpp/trunk/modules/edit/htdocs/app/cache-manifest.cmf
index 58371aa6b5..1d9464bea6 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/app/cache-manifest.cmf.off
+++ b/sca-cpp/trunk/modules/edit/htdocs/app/cache-manifest.cmf
@@ -6,7 +6,6 @@ CACHE MANIFEST
# App resources
/
-/app.html
/data/index.html
/favicon.ico
/footconfig.js
diff --git a/sca-cpp/trunk/modules/edit/htdocs/app/frame.html b/sca-cpp/trunk/modules/edit/htdocs/app/frame.html
index 7e313d2138..3509e1e190 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/app/frame.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/app/frame.html
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html>
+<html manifest="/cache-manifest.cmf">
<head>
<title></title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
diff --git a/sca-cpp/trunk/modules/edit/htdocs/app/index.html b/sca-cpp/trunk/modules/edit/htdocs/app/index.html
index 8d0a3f7153..f62cc5d0eb 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/app/index.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/app/index.html
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html>
+<html manifest="/cache-manifest.cmf">
<head>
<title></title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
@@ -30,8 +30,8 @@ document.title = window.location.hostname.split('.')[0];
<link rel="stylesheet" type="text/css" href="/ui-min.css"/>
<script type="text/javascript" src="/all-min.js"></script>
</head>
-<body class="delayed" onload="ui.onload();">
-<div id="bodydiv" class="devicewidth">
+<body class="delayed" onload="ui.onload();" onbeforeunload="ui.onbeforeunload();">
+<div id="bodydiv" class="bodydiv">
<div id="headdiv" class="hsection">
<script type="text/javascript" src="/headconfig.js"></script>
@@ -45,6 +45,8 @@ document.title = window.location.hostname.split('.')[0];
</div>
<script type="text/javascript">
+ui.initbody();
+
/**
* The main app div.
*/
@@ -120,49 +122,123 @@ function inputvalue(e) {
*/
function setwidgetvalue(e, dv) {
var htattrs = namedElementChild("'htattrs", dv);
- var attrs = append(isNil(htattrs)? mklist() :
- map(function(ce) { return mklist(elementName(ce).substring(1), elementHasValue(ce)? elementValue(ce) : elementChildren(ce)); }, elementChildren(htattrs)),
- elementHasValue(dv)? mklist(mklist('value', isNil(elementValue(dv))? '' : elementValue(dv))) : mklist());
+
+ function attr(ce) {
+ return mklist(elementName(ce) == "'htstyle"? 'style' : elementName(ce).substring(1), elementHasValue(ce)? elementValue(ce) : elementChildren(ce));
+ }
+
+ function vattr(dv) {
+ return (elementHasValue(dv) && !isNil(elementValue(dv)))? mklist(mklist('value', isNil(elementValue(dv))? '' : elementValue(dv))) : mklist();
+ }
+
+ function sattr(dv) {
+ var s = namedElementChild("'htstyle", dv);
+ return isNil(s)? mklist() : mklist(mklist('style', elementHasValue(s)? elementValue(s) : elementChildren(s)))
+ }
+
+ var attrs = append(append(isNil(htattrs)? mklist() : map(attr, elementChildren(htattrs)), vattr(dv)), sattr(dv));
+
+ // Set the attributes of the widget
+ function setattrs(vsetter, attrs, ce) {
+ return map(function(a) {
+ if (car(a) == 'value')
+ return vsetter(a, ce);
+
+ if (car(a) == 'style') {
+ // Split a style property between a style attribute
+ // and a stylesheet definition in the document's head
+
+ function prop(s) {
+ if (s == ';')
+ return '';
+ var i = s.indexOf('<style>');
+ if (i == -1)
+ return s;
+ var j = s.indexOf('</style>');
+ return s.substring(0, i) + prop(s.substring(j + 8));
+ }
+
+ function sheet(s) {
+ var i = s.indexOf('<style>');
+ if (i == -1)
+ return '';
+ var j = s.indexOf('</style>');
+ return s.substring(i + 7, j) + sheet(s.substring(j + 8));
+ }
+
+ var st = cadr(a).replace(new RegExp('{id}', 'g'), e.id);
+ var p = prop(st);
+ var s = sheet(st);
+
+ // Define the stylesheet
+ if (s != '') {
+ var esheet = appframe.contentDocument.getElementById('style_' + e.id);
+ if (isNil(esheet)) {
+ var nesheet = document.createElement('style');
+ nesheet.id = 'style_' + e.id;
+ nesheet.type = 'text/css';
+ appframe.contentDocument.getElementsByTagName('head')[0].appendChild(nesheet);
+ nesheet.innerHTML = s;
+ } else {
+ esheet.innerHTML = s;
+ }
+ }
+
+ var aname = ce.style.webkitAnimationName;
+
+ // Set the style attribute
+ ce.setAttribute('style', p);
+
+ // Restart current animation if necessary
+ if (!isNil(aname) && ce.style.webkitAnimationName == aname) {
+ ce.style.webkitAnimationName = '';
+ setTimeout(function() {
+ ce.style.webkitAnimationName = aname;
+ }, 0);
+ }
+ return a;
+ }
+
+ ce.setAttribute(car(a), cadr(a));
+ return a;
+ }, attrs);
+ }
if (e.className == 'h1' || e.className == 'h2' || e.className == 'text' || e.className == 'section') {
var ce = car(childElements(e));
- return map(function(a) { car(a) == 'value'? ce.innerHTML = cadr(a) : ce.setAttribute(car(a), cadr(a)); }, attrs);
+ return setattrs(function(a, ce) { ce.innerHTML = cadr(a); }, attrs, ce);
}
-
if (e.className == 'entry' || e.className == 'password') {
var ce = car(childElements(e));
- return map(function(a) { car(a) == 'value'? ce.defaultValue = cadr(a) : ce.setAttribute(car(a), cadr(a)); }, attrs);
+ return setattrs(function(a, ce) { ce.defaultValue = cadr(a); }, attrs, ce);
}
-
if (e.className == 'button') {
var ce = car(childElements(e));
- return map(function(a) { car(a) == 'value'? ce.value = cadr(a) : ce.setAttribute(car(a), cadr(a)); }, attrs);
+ return setattrs(function(a, ce) { ce.value = cadr(a); }, attrs, ce);
}
-
if (e.className == 'checkbox') {
var ce = car(childElements(e));
- function setcheckvalue(ce, v) {
+ function setcheckvalue(a, ce) {
+ var v = cadr(a);
ce.value = v;
map(function(n) { if (n.nodeName == "SPAN") n.innerHTML = v; return n; }, nodeList(e.childNodes));
return true;
}
- var r = map(function(a) { car(a) == 'value'? setcheckvalue(ce, cadr(a)) : ce.setAttribute(car(a), cadr(a)); }, attrs);
- return r;
+ return setattrs(setcheckvalue, attrs, ce);
}
-
if (e.className == 'select') {
var ce = car(childElements(car(childElements(e))));
- function setselectvalue(ce, v) {
+ function setselectvalue(a, ce) {
+ var v = cadr(a);
ce.value = v;
ce.innerHTML = v;
return true;
}
- var r = map(function(a) { car(a) == 'value'? setselectvalue(ce, cadr(a)) : ce.setAttribute(car(a), cadr(a)); }, attrs);
- return r;
+ return setattrs(setselectvalue, attrs, ce);
}
if (e.className == 'list') {
var dl = ui.datalist(isNil(dv)? mklist() : mklist(dv));
@@ -177,7 +253,8 @@ function setwidgetvalue(e, dv) {
if (e.className == 'link') {
var ce = car(childElements(e));
- function setlinkvalue(ce, v) {
+ function setlinkvalue(a, ce) {
+ var v = cadr(a);
if (isList(v)) {
ce.href = car(v);
ce.innerHTML = cadr(v);
@@ -188,15 +265,15 @@ function setwidgetvalue(e, dv) {
return true;
}
- return map(function(a) { car(a) == 'value'? setlinkvalue(ce, cadr(a)) : ce.setAttribute(car(a), cadr(a)); }, attrs);
+ return setattrs(setlinkvalue, attrs, ce);
}
if (e.className == 'img') {
var ce = car(childElements(e));
- return map(function(a) { car(a) == 'value'? ce.setAttribute('src', cadr(a)) : ce.setAttribute(car(a), cadr(a)); }, attrs);
+ return setattrs(function(a, ce) { ce.setAttribute('src', cadr(a)); }, attrs, ce);
}
if (e.className == 'iframe') {
var ce = car(childElements(e));
- return map(function(a) { car(a) == 'value'? ce.setAttribute('src', cadr(a)) : ce.setAttribute(car(a), cadr(a)); }, attrs);
+ return setattrs(function(a, ce) { ce.setAttribute('src', cadr(a)); }, attrs, ce);
}
return '';
};
@@ -250,6 +327,19 @@ function bindwidgethandler(e) {
b.onclick = function() { return buttonClickHandler(b.value); };
return e;
}
+ if (e.className == 'link') {
+ var l = car(childElements(e));
+ var hr = l.href;
+ if (hr.substring(0, 5) == 'link:' && hr.indexOf('://') == -1) {
+ var f = function(e) {
+ e.preventDefault();
+ return buttonClickHandler(hr.substring(5));
+ };
+ l.ontouchstart = l.onclick = f;
+ l.href = 'javascript:void()';
+ }
+ return e;
+ }
if (e.className == 'entry' || e.className == 'password' || e.className == 'checkbox') {
car(childElements(e)).name = e.id;
return e;
@@ -266,13 +356,40 @@ function bindwidgethandler(e) {
* Initial fixup of a widget.
*/
function fixupwidget(e) {
- if (e.className == 'iframe') {
- var f = car(childElements(e));
- e.innerHTML = '<iframe src="' + f.href + '" frameborder="no" scrolling="no"></iframe>';
+ if (e.className == 'h1' || e.className == 'h2' || e.className == 'text' || e.className == 'section') {
+ if (e.className == 'section')
+ e.style.width = '100%';
+ var ce = car(childElements(e));
+ if (ce.innerHTML == '=' + e.id)
+ ce.innerHTML = '';
return e;
}
- if (e.className == 'section') {
- e.style.width = '100%';
+ if (e.className == 'entry' || e.className == 'password') {
+ var ce = car(childElements(e));
+ if (ce.defaultValue == '=' + e.id)
+ ce.defaultValue = '';
+ return e;
+ }
+ if (e.className == 'button') {
+ var ce = car(childElements(e));
+ if (ce.value == '=' + e.id)
+ ce.value = '';
+ return e;
+ }
+ if (e.className == 'checkbox') {
+ var ce = car(childElements(e));
+ if (ce.value == '=' + e.id) {
+ ce.value = '';
+ map(function(n) { if (n.nodeName == "SPAN") n.innerHTML = ''; return n; }, nodeList(e.childNodes));
+ }
+ return e;
+ }
+ if (e.className == 'select') {
+ var ce = car(childElements(car(childElements(e))));
+ if (ce.value == '=' + e.id) {
+ ce.value = '';
+ ce.innerHTML = '';
+ }
return e;
}
if (e.className == 'list') {
@@ -287,6 +404,21 @@ function fixupwidget(e) {
car(childElements(e)).style.width = '100%';
return e;
}
+ if (e.className == 'link') {
+ var ce = car(childElements(e));
+ if (ce.innerHTML == '=' + e.id)
+ ce.innerHTML = '';
+ return e;
+ }
+ if (e.className == 'img') {
+ var ce = car(childElements(e));
+ return e;
+ }
+ if (e.className == 'iframe') {
+ var ce = car(childElements(e));
+ e.innerHTML = '<iframe src="' + ce.href + '" frameborder="no" scrolling="no"></iframe>';
+ return e;
+ }
return e;
}
@@ -304,7 +436,7 @@ function initwidget(e) {
*/
function getdoc(comp, name, uri) {
try {
- return comp.get(uri);
+ return comp.getnocache(uri);
} catch(e) {
log('exception on get(' + name + ', ' + uri + ')', e);
return null;
diff --git a/sca-cpp/trunk/modules/edit/htdocs/clone/index.html b/sca-cpp/trunk/modules/edit/htdocs/clone/index.html
index 5e3922a28e..29ebe1ce06 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/clone/index.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/clone/index.html
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html>
+<html manifest="/cache-manifest.cmf">
<head>
<title></title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
@@ -28,8 +28,8 @@
<script type="text/javascript" src="/all-min.js"></script>
<script type="text/javascript" src="/menu.js"></script>
</head>
-<body class="delayed" onload="ui.onload();">
-<div id="bodydiv" class="devicewidth">
+<body class="delayed" onload="ui.onload();" onbeforeunload="ui.onbeforeunload();">
+<div id="bodydiv" class="bodydiv">
<div id="headdiv" class="hsection">
<script type="text/javascript" src="/headconfig.js"></script>
@@ -62,15 +62,17 @@
<tr><tr><td style="padding-top: 6px;"><b>Description:</b></td></tr>
<tr><td><textarea id="appDescription" cols="40" rows="3" placeholder="Enter a short description of your app" style="width: 300px;"></textarea></td></tr>
<tr><td>
-<input id="cloneAppOKButton" type="submit" class="greenbutton" style="font-weight: bold;" value="Clone" title="Clone the app"/>
-<input id="cloneAppCancelButton" type="button" class="redbutton" value="Cancel"/>
+<input id="cloneAppOKButton" type="submit" class="graybutton" style="font-weight: bold;" value="Clone" title="Clone the app"/>
+<input id="cloneAppCancelButton" type="button" class="graybutton" value="Cancel"/>
</td></tr>
</table>
</form>
<script type="text/javascript">
+ui.initbody();
+
// Get the app name
-var appname = ui.queryParams()['app'];
+var appname = ui.fragmentParams()['app'];
if (isNil(appname))
window.open('/', '_self');
@@ -90,8 +92,7 @@ function applink(appname) {
// Set page titles
var tclone = isNil(config.clone)? 'Clone' : config.clone;
document.title = windowtitle(window.location.hostname) + ' - ' + tclone + ' - ' + appname;
-//$('h1').innerHTML = hometitle(window.location.hostname);
-$('appNameHeader').innerHTML = '<a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '.' + window.location.hostname + '</a>';
+$('appNameHeader').innerHTML = '<a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '</a>';
$('th').innerHTML = tclone + ' this App';
$('cloneAppOKButton').value = tclone;
$('cloneAppOKButton').title = tclone + ' this app';
@@ -120,6 +121,11 @@ function getapp(name) {
if (isNil(name))
return false;
return apps.get(name, function(doc) {
+
+ // Stop now if we didn't get the app
+ if (doc == null)
+ return false;
+
appentry = doc != null? car(elementsToValues(atom.readATOMEntry(mklist(doc)))) : mklist("'entry", mklist("'title", ''), mklist("'id", name));
var title = cadr(assoc("'title", cdr(appentry)));
$('appTitle').value = title;
@@ -141,10 +147,14 @@ $('cloneAppForm').onsubmit = function() {
var title = $('appTitle').value;
var app = mklist(mklist("'entry", mklist("'title", title != ''? title : name), mklist("'id", appname)));
var entry = atom.writeATOMEntry(valuesToElements(app));
- dashboards.put(name, car(entry));
+ dashboards.put(name, car(entry), function(e) {
+ if (e)
+ return false;
- // Open it in the page editor
- window.open('/page/?app=' + name, '_self');
+ // Open it in the page editor
+ ui.navigate('/page/#app=' + name, '_self');
+ return false;
+ });
return false;
};
@@ -152,7 +162,7 @@ $('cloneAppForm').onsubmit = function() {
* Cancel cloning an app.
*/
$('cloneAppCancelButton').onclick = function() {
- window.open('/stats/?app=' + appname, '_self');
+ ui.navigate('/stats/#app=' + appname, '_self');
};
// Get the current app
diff --git a/sca-cpp/trunk/modules/edit/htdocs/create/index.html b/sca-cpp/trunk/modules/edit/htdocs/create/index.html
index bf8f71f7e9..575016aeb8 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/create/index.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/create/index.html
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html>
+<html manifest="/cache-manifest.cmf">
<head>
<title>Create App</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
@@ -28,8 +28,8 @@
<script type="text/javascript" src="/all-min.js"></script>
<script type="text/javascript" src="/menu.js"></script>
</head>
-<body class="delayed" onload="ui.onload();">
-<div id="bodydiv" class="devicewidth">
+<body class="delayed" onload="ui.onload();" onbeforeunload="ui.onbeforeunload();">
+<div id="bodydiv" class="bodydiv">
<div id="headdiv" class="hsection">
<script type="text/javascript" src="/headconfig.js"></script>
@@ -60,13 +60,15 @@
<tr><tr><td style="padding-top: 6px;"><b>Description:</b></td></tr>
<tr><td><textarea id="appDescription" cols="40" rows="3" placeholder="Enter a short description of your app" style="width: 300px;"></textarea></td></tr>
<tr><td>
-<input id="createAppOKButton" type="submit" class="greenbutton" style="font-weight: bold;" value="Create" title="Create the app"/>
-<input id="createAppCancelButton" type="button" class="redbutton" value="Cancel"/>
+<input id="createAppOKButton" type="submit" class="graybutton" style="font-weight: bold;" value="Create" title="Create the app"/>
+<input id="createAppCancelButton" type="button" class="graybutton" value="Cancel"/>
</td></tr>
</table>
</form>
<script type="text/javascript">
+ui.initbody();
+
// Set page titles
document.title = windowtitle(window.location.hostname) + ' - Create App';
$('h1').innerHTML = hometitle(window.location.hostname);
@@ -94,10 +96,14 @@ $('createAppForm').onsubmit = function() {
var title = $('appTitle').value;
var app = mklist(mklist("'entry", mklist("'title", title != ''? title : name), mklist("'id", 'new')));
var entry = atom.writeATOMEntry(valuesToElements(app));
- dashboards.put(name, car(entry));
+ dashboards.put(name, car(entry), function(e) {
+ if (e)
+ return false;
- // Open it in the page editor
- window.open('/page/?app=' + name, '_self');
+ // Open it in the page editor
+ ui.navigate('/page/#app=' + name, '_self');
+ return false;
+ });
return false;
};
@@ -105,7 +111,7 @@ $('createAppForm').onsubmit = function() {
* Cancel creating an app.
*/
$('createAppCancelButton').onclick = function() {
- return window.open('/store/', '_self');
+ return ui.navigate('/store/', '_self');
};
</script>
diff --git a/sca-cpp/trunk/modules/edit/htdocs/data/index.html b/sca-cpp/trunk/modules/edit/htdocs/data/index.html
index 1f583adc3b..23b8668ce4 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/data/index.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/data/index.html
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html>
+<html manifest="/cache-manifest.cmf">
<head>
<title>View</title>
<script type="text/javascript">
@@ -31,7 +31,7 @@ document.title = 'View - ' + window.location.hostname.split('.')[0] + '/' + cn;
<link rel="stylesheet" type="text/css" href="/ui-min.css">
<script type="text/javascript" src="/all-min.js"></script>
</head>
-<body class="delayed" onload="ui.onload();">
+<body class="delayed" onload="ui.onload();" onbeforeunload="ui.onbeforeunload();">
<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;">
<div id="compLinkHeader" style="margin-top: 4px; margin-bottom: 4px;"></div>
@@ -39,8 +39,10 @@ document.title = 'View - ' + window.location.hostname.split('.')[0] + '/' + cn;
</div>
<script type="text/javascript">
+ui.initbody();
+
// Get the component name
-var cname = ui.queryParams()['component'];
+var cname = ui.fragmentParams()['component'];
/**
* The current component.
@@ -74,7 +76,12 @@ function mkdoctable(doc) {
* Get and display the contents of the current component.
*/
function getdata() {
- return comp.get('', function(doc) {
+ return comp.getnocache('', function(doc) {
+
+ // Stop now if we didn't the doc
+ if (doc == null)
+ return false;
+
if (json.isJSON(mklist(doc)))
return display(datatable(json.readJSON(mklist(doc))));
diff --git a/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js
index 2ef53fa54a..d459a4b021 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js
+++ b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js
@@ -18,7 +18,7 @@
*/
/**
- * SVG and VML composite rendering functions.
+ * SVG composite rendering functions.
*/
var graph = {};
@@ -40,18 +40,39 @@ graph.colors.purple = '#800080';
graph.colors.red = '#ff0000';
graph.colors.white = '#ffffff';
graph.colors.yellow = '#ffff00';
-
graph.colors.link = '#598edd';
-graph.colors.orange1 = '#ffbb00';
-graph.colors.green1 = '#96d333';
-//graph.colors.blue1 = '#00c3c9';
-graph.colors.blue1 = '#0d7cc1';
+graph.colors.orange1 = '#ffd666';
+graph.colors.green1 = '#bbe082';
+graph.colors.blue1 = '#66dbdf';
+graph.colors.yellow1 = '#fdf57a';
+graph.colors.cyan1 = '#e6eafb';
+graph.colors.lightgray1 = '#eaeaea'
+graph.colors.pink1 = '#ffd9e0';
graph.colors.red1 = '#d03f41';
-graph.colors.yellow1 = '#fcee21';
-graph.colors.magenta1 = '#c0688a';
-graph.colors.cyan1 = '#d5dcf9';
-graph.colors.lightgray1 = '#dcdcdc'
+graph.colors.white1 = '#ffffff';
+
+graph.colors.orange2 = '#ffbb00';
+graph.colors.green2 = '#96d333';
+//graph.colors.blue2 = '#0d7cc1';
+graph.colors.blue2 = '#00c3c9';
+graph.colors.red2 = '#d03f41';
+graph.colors.yellow2 = '#fcee21';
+graph.colors.magenta2 = '#c0688a';
+graph.colors.cyan2 = '#d5dcf9';
+graph.colors.lightgray2 = '#dcdcdc'
+graph.colors.pink2 = '#ffc0cb';
+graph.colors.white2 = '#ffffff';
+
+graph.colors.orange3 = '#ffc700';
+graph.colors.green3 = '#92e120';
+graph.colors.blue3 = '#008fd1';
+graph.colors.yellow3 = '#fdf400';
+graph.colors.cyan3 = '#b4d3fd';
+graph.colors.lightgray3 = '#e3e3e3'
+graph.colors.pink3 = '#da749b';
+graph.colors.red3 = '#ed3f48';
+graph.colors.white3 = '#ffffff';
/**
* Default positions and sizes.
@@ -59,50 +80,14 @@ graph.colors.lightgray1 = '#dcdcdc'
var palcx = 2500;
var proxcx = 20;
var proxcy = 20;
-var buttoncx = 65;
-var buttoncy = 30;
-var curvsz = 6;
+var buttoncx = 55;
+var buttoncy = 23;
+var curvsz = 4;
var tabsz = 2;
-var fontsz = '11px';
-
-/**
- * Base path class.
- */
-graph.BasePath = function() {
- this.path = '';
- this.x = 0;
- this.y = 0;
-
- this.pos = function(x, y) {
- this.x = x;
- this.y = y;
- return this;
- };
-
- this.xpos = function() {
- return this.x;
- };
-
- this.ypos = function() {
- return this.y;
- };
-
- this.rmove = function(x, y) {
- return this.move(this.x + x, this.y + y);
- };
-
- this.rline = function(x, y) {
- return this.line(this.x + x, this.y + y);
- };
-
- this.rcurve = function(x1, y1, x, y) {
- return this.curve(this.x + x1, this.y + y1, this.x + x1 + x, this.y + y1 + y);
- };
-
- this.str = function() {
- return this.path;
- };
-};
+var titlex = 4;
+var titley = 11;
+var titlesp = 3;
+var titlew = ui.isMobile()? -2 : 0;
/**
* SVG rendering functions.
@@ -113,7 +98,7 @@ graph.svgns='http://www.w3.org/2000/svg';
/**
* Make an SVG graph.
*/
-graph.mkgraph = function(cdiv, pos, cvalue, cadd, cdelete) {
+graph.mkgraph = function(cdiv, pos, cvalue, cadd, ccopy, cdelete) {
// Create a div element to host the graph
var div = document.createElement('div');
@@ -121,7 +106,7 @@ graph.mkgraph = function(cdiv, pos, cvalue, cadd, cdelete) {
div.style.position = 'absolute';
div.style.left = ui.pixpos(pos.xpos() + cdiv.offsetLeft);
div.style.top = ui.pixpos(pos.ypos() + cdiv.offsetTop);
- div.style.overflow = 'hidden';
+ //div.style.overflow = 'hidden';
cdiv.appendChild(div);
// Create SVG element
@@ -132,8 +117,11 @@ graph.mkgraph = function(cdiv, pos, cvalue, cadd, cdelete) {
// Track element dragging and selection
graph.dragging = null;
+ graph.dragged = false;
+ graph.moverenderer = null;
graph.selected = null;
cvalue.disabled = true;
+ ccopy.disabled = true;
cdelete.disabled = true;
/**
@@ -148,50 +136,87 @@ graph.mkgraph = function(cdiv, pos, cvalue, cadd, cdelete) {
}
/**
- * Handle a mouse down event.
+ * Handle a mouse down or touch start event.
*/
- div.onmousedown = function(e) {
+ function onmousedown(e) {
+
+ // Remember mouse or touch position
+ var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
+ graph.downX = pos.screenX;
+ graph.downY = pos.screenY;
+ graph.moveX = pos.screenX;
+ graph.moveY = pos.screenY;
- // On mouse controlled devices, engage the click component selection
- // logic right away
+ // Engage the click component selection right away
+ // on mouse controlled devices
if (typeof e.touches == 'undefined')
- div.onclick(e);
+ onclick(e);
- // Find draggable component
+ // Find and remember draggable component
var dragging = draggable(e.target);
if (dragging == null || dragging != graph.selected)
return true;
graph.dragging = dragging;
+ graph.dragged = false;
- // Remember current mouse position
- var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
+ // Remember current drag position
graph.dragX = pos.screenX;
graph.dragY = pos.screenY;
- if (e.preventDefault)
- e.preventDefault();
- else
- e.returnValue = false;
+ e.preventDefault();
return true;
};
- // Support touch devices
- div.ontouchstart = div.onmousedown;
+ if (!ui.isMobile()) {
+ div.onmousedown = function(e) {
+ //log('onmousedown');
+ var suspend = svg.suspendRedraw(10);
+ var r = onmousedown(e);
+ svg.unsuspendRedraw(suspend);
+ return r;
+ }
+ } else {
+ div.ontouchstart = function(e) {
+ //log('ontouchstart');
+
+ // Clear current move renderer if it's running
+ if (!isNil(graph.moverenderer)) {
+ clearInterval(graph.moverenderer);
+ graph.moverenderer = null;
+ }
+
+ var suspend = svg.suspendRedraw(10);
+ var r = onmousedown(e);
+ svg.unsuspendRedraw(suspend);
+ return r;
+ }
+ }
/**
- * Handle a mouse up event.
+ * Handle a mouse up or touch end event.
*/
- div.onmouseup = function(e) {
+ function onmouseup(e) {
+
+ // Engage the click component selection now on touch devices
+ if (ui.isMobile()) {
+ if (!graph.dragged && graph.moveX == graph.downX && graph.moveY == graph.downY)
+ return onclick(e);
+ }
+
+ // Stop here if the component was not dragged
if (graph.dragging == null)
return true;
+ if (!graph.dragged) {
+ graph.dragging = null;
+ return true;
+ }
if (graph.dragging.parentNode == svg && graph.dragging.id.substring(0, 8) != 'palette:') {
- var gpos = graph.relpos(graph.dragging);
// Add new dragged component to the composite
if (isNil(graph.dragging.compos)) {
var compos = scdl.composite(svg.compos);
- setElement(compos, graph.sortcompos(graph.addcomp(graph.dragging.comp, compos)));
+ setElement(compos, graph.sortcompos(graph.addcomps(mklist(graph.dragging.comp), compos)));
graph.dragging.compos = svg.compos;
}
@@ -207,34 +232,62 @@ graph.mkgraph = function(cdiv, pos, cvalue, cadd, cdelete) {
// Snap top level component position to grid
if (graph.dragging.parentNode == svg) {
var gpos = graph.relpos(graph.dragging);
- graph.move(graph.dragging, graph.mkpath().move(graph.gridsnap(gpos.xpos()), graph.gridsnap(gpos.ypos())));
- setElement(graph.dragging.comp, graph.movecomp(graph.dragging.comp, graph.abspos(graph.dragging, svg)));
+ setElement(graph.dragging.comp, graph.movecomp(graph.dragging.comp, graph.mkpath().pos(graph.gridsnap(gpos.xpos()), graph.gridsnap(gpos.ypos()))));
}
}
// Forget current dragged component
graph.dragging = null;
+ graph.dragged = false;
// Refresh the composite
+ //log('onmouseup refresh');
var nodes = graph.refresh(svg);
// Reselected the previously selected component
- graph.selected = graph.findcompnode(scdl.name(graph.selected.comp), nodes);
- graph.compselect(graph.selected, true, cvalue, cdelete);
+ if (!isNil(graph.selected)) {
+ graph.selected = graph.findcompnode(scdl.name(graph.selected.comp), nodes);
+ graph.compselect(graph.selected, true, cvalue, ccopy, cdelete);
- // Trigger component select event
- svg.oncompselect(graph.selected);
+ // Trigger component select event
+ svg.oncompselect(graph.selected);
+ }
// Trigger composite change event
svg.oncomposchange(false);
return true;
};
- // Support touch devices
- div.ontouchend = div.onmouseup;
+ if (!ui.isMobile()) {
+ div.onmouseup = function(e) {
+ //log('onmouseup');
+ var suspend = svg.suspendRedraw(10);
+ var r = onmouseup(e);
+ svg.unsuspendRedraw(suspend);
+ return r;
+ }
+ } else {
+ div.ontouchend = function(e) {
+ //log('ontouchend');
+
+ // Clear current move renderer if it's running
+ if (!isNil(graph.moverenderer)) {
+ clearInterval(graph.moverenderer);
+ graph.moverenderer = null;
+ }
- // Handle a mouse click event.
- div.onclick = svg.onclick = function(e) {
+ var suspend = svg.suspendRedraw(10);
+ var r = onmouseup(e);
+ svg.unsuspendRedraw(suspend);
+ return r;
+ }
+ }
+
+ /**
+ * Handle a mouse or touch click event.
+ */
+ function onclick(e) {
+ //log('onclick logic');
// Find selected component
var selected = draggable(e.target);
@@ -242,7 +295,7 @@ graph.mkgraph = function(cdiv, pos, cvalue, cadd, cdelete) {
if (graph.selected != null) {
// Reset current selection
- graph.compselect(graph.selected, false, cvalue, cdelete);
+ graph.compselect(graph.selected, false, cvalue, ccopy, cdelete);
graph.selected = null;
// Trigger component select event
@@ -263,29 +316,24 @@ graph.mkgraph = function(cdiv, pos, cvalue, cadd, cdelete) {
return true;
// Deselect previously selected component
- graph.compselect(graph.selected, false, cvalue, cdelete);
+ graph.compselect(graph.selected, false, cvalue, ccopy, cdelete);
// Clone component from the palette
if (selected.id.substring(0, 8) == 'palette:') {
var compos = scdl.composite(svg.compos);
- graph.selected = graph.clonepalette(selected, compos, svg);
- setElement(compos, graph.sortcompos(graph.addcomp(graph.selected.comp, compos)));
- graph.selected.compos = svg.compos;
+ var comp = graph.clonepalette(selected, compos, svg);
+ setElement(compos, graph.sortcompos(graph.addcomps(mklist(comp), compos)));
// Move into the editing area and hide the palette
- var gpos = graph.relpos(graph.selected);
- graph.move(graph.selected, graph.mkpath().move(gpos.xpos() + palcx, gpos.ypos()));
div.style.left = ui.pixpos(palcx * -1);
- // Update component position
- setElement(graph.selected.comp, graph.movecomp(graph.selected.comp, graph.abspos(graph.selected, svg)));
-
// Refresh the composite
+ //log('onclick refresh');
var nodes = graph.refresh(svg);
// Reselect the previously selected component
- graph.selected = graph.findcompnode(scdl.name(graph.selected.comp), nodes);
- graph.compselect(graph.selected, true, cvalue, cdelete);
+ graph.selected = graph.findcompnode(scdl.name(comp), nodes);
+ graph.compselect(graph.selected, true, cvalue, ccopy, cdelete);
// Trigger component select event
svg.oncompselect(graph.selected);
@@ -297,12 +345,14 @@ graph.mkgraph = function(cdiv, pos, cvalue, cadd, cdelete) {
graph.selected = selected;
// Select the component
- graph.compselect(graph.selected, true, cvalue, cdelete);
+ graph.compselect(graph.selected, true, cvalue, ccopy, cdelete);
// Trigger component select event
svg.oncompselect(graph.selected);
}
+ //log('comp selected');
+
if (e.preventDefault)
e.preventDefault();
else
@@ -310,18 +360,37 @@ graph.mkgraph = function(cdiv, pos, cvalue, cadd, cdelete) {
return true;
}
+ if (!ui.isMobile()) {
+ div.onclick = function(e) {
+ //log('div onclick');
+ var suspend = svg.suspendRedraw(10);
+ var r = onclick(e);
+ svg.unsuspendRedraw(suspend);
+ return r;
+ }
+ svg.onclick = function(e) {
+ //log('svg onclick');
+ var suspend = svg.suspendRedraw(10);
+ var r = onclick(e);
+ svg.unsuspendRedraw(suspend);
+ return r;
+ }
+ }
+
/**
- * Handle a mouse move event.
+ * Handle a mouse or touch move event.
*/
- window.onmousemove = function(e) {
+ function onmousemove(e) {
if (graph.dragging == null)
return true;
- // Get the mouse position
- var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
- if (pos.screenX == graph.dragX && pos.screenY == graph.dragY)
+ // Ignore duplicate mouse move events
+ if (graph.moveX == graph.dragX && graph.moveY == graph.dragY)
return true;
+ // Remember that the component was dragged
+ graph.dragged = true;
+
// Cut wire to component
if (graph.dragging.parentNode != svg) {
var compos = scdl.composite(svg.compos);
@@ -333,30 +402,68 @@ graph.mkgraph = function(cdiv, pos, cvalue, cadd, cdelete) {
// Calculate new position of dragged element
var gpos = graph.relpos(graph.dragging);
- var newX = gpos.xpos() + (pos.screenX - graph.dragX);
- var newY = gpos.ypos() + (pos.screenY - graph.dragY);
+ var newX = gpos.xpos() + (graph.moveX - graph.dragX);
+ var newY = gpos.ypos() + (graph.moveY - graph.dragY);
if (newX >= palcx)
- graph.dragX = pos.screenX;
+ graph.dragX = graph.moveX
else
newX = palcx;
if (newY >= 0)
- graph.dragY = pos.screenY;
+ graph.dragY = graph.moveY;
else
newY = 0;
+ // Detach child elements to speedup rendering
+ graph.compoutline(graph.dragging, true);
+
// Move the dragged element
- graph.move(graph.dragging, graph.mkpath().move(newX, newY));
+ graph.move(graph.dragging, graph.mkpath().pos(newX, newY));
- return true;
+ return false;
};
- // Support touch devices
- div.ontouchmove = window.onmousemove;
+ if (!ui.isMobile()) {
+ window.onmousemove = function(e) {
+ //log('onmousemove');
+
+ // Remember mouse position
+ graph.moveX = e.screenX;
+ graph.moveY = e.screenY;
+
+ var suspend = svg.suspendRedraw(10);
+ var r = onmousemove(e);
+ svg.unsuspendRedraw(suspend);
+ return r;
+ }
+ } else {
+ div.ontouchmove = function(e) {
+ //log('ontouchmove');
+
+ // Remember touch position
+ var pos = e.touches[0];
+ if (graph.moveX == pos.screenX && graph.moveY == pos.screenY)
+ return true;
+ graph.moveX = pos.screenX;
+ graph.moveY = pos.screenY;
+ if (graph.moveX == graph.dragX && graph.moveY == graph.dragY)
+ return true;
+
+ // Start async move renderer
+ if (graph.moverenderer == null) {
+ graph.moverenderer = setInterval(function() {
+ var suspend = svg.suspendRedraw(10);
+ onmousemove(e);
+ svg.unsuspendRedraw(suspend);
+ }, 10);
+ }
+ return true;
+ }
+ }
/**
* Handle field on change events.
*/
- cvalue.onchange = function() {
+ function onvaluechange() {
if (graph.selected == null)
return false;
if (g.parentNode.style.visibility == 'hidden')
@@ -370,11 +477,12 @@ graph.mkgraph = function(cdiv, pos, cvalue, cadd, cdelete) {
setElement(compos, graph.sortcompos(graph.renamecomp(graph.selected.comp, compos, cvalue.value)));
// Refresh the composite
+ //log('onchangename refresh');
var nodes = graph.refresh(svg);
// Reselected the previously selected component
graph.selected = graph.findcompnode(scdl.name(graph.selected.comp), nodes);
- graph.compselect(graph.selected, true, cvalue, cdelete);
+ graph.compselect(graph.selected, true, cvalue, ccopy, cdelete);
// Trigger component select event
svg.oncompselect(graph.selected);
@@ -391,11 +499,12 @@ graph.mkgraph = function(cdiv, pos, cvalue, cadd, cdelete) {
cvalue.disabled = !graph.hasproperty(graph.selected.comp);
// Refresh the composite
+ //log('onchangeprop refresh');
var nodes = graph.refresh(svg);
// Reselected the previously selected component
graph.selected = graph.findcompnode(scdl.name(graph.selected.comp), nodes);
- graph.compselect(graph.selected, true, cvalue, cdelete);
+ graph.compselect(graph.selected, true, cvalue, ccopy, cdelete);
// Trigger component select event
svg.oncompselect(graph.selected);
@@ -407,9 +516,16 @@ graph.mkgraph = function(cdiv, pos, cvalue, cadd, cdelete) {
return graph.hasproperty(graph.selected.comp)? changeprop() : changename();
};
+
+ cvalue.onchange = function() {
+ var suspend = svg.suspendRedraw(10);
+ var r = onvaluechange();
+ svg.unsuspendRedraw(suspend);
+ return r;
+ }
// Handle delete event
- cdelete.onclick = function() {
+ function ondeleteclick() {
if (graph.selected == null)
return false;
if (graph.selected.id.substring(0, 8) != 'palette:') {
@@ -421,10 +537,11 @@ graph.mkgraph = function(cdiv, pos, cvalue, cadd, cdelete) {
setElement(compos, graph.sortcompos(graph.clonerefs(graph.gcollect(graph.removecomp(graph.selected.comp, compos)))));
// Reset current selection
- graph.compselect(graph.selected, false, cvalue, cdelete);
+ graph.compselect(graph.selected, false, cvalue, ccopy, cdelete);
graph.selected = null;
// Refresh the composite
+ //log('ondelete refresh');
graph.refresh(svg);
// Trigger component select event
@@ -436,6 +553,49 @@ graph.mkgraph = function(cdiv, pos, cvalue, cadd, cdelete) {
return false;
};
+ cdelete.onclick = function() {
+ var suspend = svg.suspendRedraw(10);
+ var r = ondeleteclick();
+ svg.unsuspendRedraw(suspend);
+ return r;
+ };
+
+ // Handle copy event
+ function oncopyclick() {
+ if (graph.selected == null)
+ return false;
+ if (graph.selected.id.substring(0, 8) == 'palette:')
+ return false;
+
+ // Clone the selected component
+ var compos = scdl.composite(svg.compos);
+ var comps = graph.clonecomp(graph.selected, compos, svg);
+ setElement(compos, graph.sortcompos(graph.addcomps(comps, compos)));
+
+ // Refresh the composite
+ //log('onclick refresh');
+ var nodes = graph.refresh(svg);
+
+ // Select the component clone
+ graph.selected = graph.findcompnode(scdl.name(car(comps)), nodes);
+ graph.compselect(graph.selected, true, cvalue, ccopy, cdelete);
+
+ // Trigger component select event
+ svg.oncompselect(graph.selected);
+
+ // Trigger composite change event
+ svg.oncomposchange(true);
+
+ return false;
+ };
+
+ ccopy.onclick = function() {
+ var suspend = svg.suspendRedraw(10);
+ var r = oncopyclick();
+ svg.unsuspendRedraw(suspend);
+ return r;
+ };
+
// Handle add event
cadd.onclick = function() {
@@ -446,65 +606,99 @@ graph.mkgraph = function(cdiv, pos, cvalue, cadd, cdelete) {
// Create a hidden SVG element to help compute the width
// of component and reference titles
- graph.titlewidthsvg = document.createElementNS(graph.svgns, 'svg');
- graph.titlewidthsvg.style.visibility = 'hidden';
- graph.titlewidthsvg.style.height = ui.pixpos(0);
- graph.titlewidthsvg.style.width = ui.pixpos(0);
- div.appendChild(graph.titlewidthsvg);
+ graph.svgtitles = document.createElementNS(graph.svgns, 'svg');
+ graph.svgtitles.style.visibility = 'hidden';
+ graph.svgtitles.style.height = ui.pixpos(0);
+ graph.svgtitles.style.width = ui.pixpos(0);
+ div.appendChild(graph.svgtitles);
return svg;
};
/**
- * Make a path.
+ * Point class.
*/
-graph.mkpath = function() {
- function Path() {
- this.BasePath = graph.BasePath;
- this.BasePath();
-
- this.clone = function() {
- return graph.mkpath().pos(this.xpos(), this.ypos());
- };
-
- this.move = function(x, y) {
- this.path += 'M' + x + ',' + y + ' ';
- return this.pos(x, y);
- };
-
- this.line = function(x, y) {
- this.path += 'L' + x + ',' + y + ' ';
- return this.pos(x, y);
- };
-
- this.curve = function(x1, y1, x, y) {
- this.path += 'Q' + x1 + ',' + y1 + ' ' + x + ',' + y + ' ';
- return this.pos(x, y);
- };
-
- this.end = function() {
- this.path += 'Z';
- return this;
- };
- }
+graph.Point = function(x, y) {
+ this.x = x;
+ this.y = y;
+};
+graph.Point.prototype.xpos = function() {
+ return this.x;
+};
+graph.Point.prototype.ypos = function() {
+ return this.y;
+};
- return new Path();
+graph.mkpoint = function(x, y) {
+ return new graph.Point(x, y);
+};
+
+/**
+ * Path class.
+ */
+graph.Path = function() {
+ this.path = '';
+ this.x = 0;
+ this.y = 0;
+}
+graph.Path.prototype.pos = function(x, y) {
+ this.x = x;
+ this.y = y;
+ return this;
+};
+graph.Path.prototype.xpos = function() {
+ return this.x;
+};
+graph.Path.prototype.ypos = function() {
+ return this.y;
+};
+graph.Path.prototype.rmove = function(x, y) {
+ return this.move(this.x + x, this.y + y);
+};
+graph.Path.prototype.rline = function(x, y) {
+ return this.line(this.x + x, this.y + y);
+};
+graph.Path.prototype.rcurve = function(x1, y1, x, y) {
+ return this.curve(this.x + x1, this.y + y1, this.x + x1 + x, this.y + y1 + y);
+};
+graph.Path.prototype.str = function() {
+ return this.path;
+};
+graph.Path.prototype.clone = function() {
+ return graph.mkpath().pos(this.xpos(), this.ypos());
+};
+graph.Path.prototype.move = function(x, y) {
+ this.path += 'M' + x + ',' + y + ' ';
+ return this.pos(x, y);
+};
+graph.Path.prototype.line = function(x, y) {
+ this.path += 'L' + x + ',' + y + ' ';
+ return this.pos(x, y);
+};
+graph.Path.prototype.curve = function(x1, y1, x, y) {
+ this.path += 'Q' + x1 + ',' + y1 + ' ' + x + ',' + y + ' ';
+ return this.pos(x, y);
+};
+graph.Path.prototype.end = function() {
+ this.path += 'Z';
+ return this;
+};
+
+graph.mkpath = function() {
+ return new graph.Path();
};
/**
* Return an element representing a title.
*/
-graph.mktitle = function(t, style) {
+graph.mktitle = function(t, x, y) {
var title = document.createElementNS(graph.svgns, 'text');
- title.setAttribute('x', 5);
- title.setAttribute('y', 15);
- title.setAttribute('text-anchor', 'start');
- if (style != '')
- title.style.cssText = style;
- if (fontsz != '')
- title.style.fontSize = fontsz;
- title.style.cursor = 'default';
+ title.setAttribute('x', x);
+ title.setAttribute('y', y);
+ title.setAttribute('class', 'svgtitle');
+ title.setAttribute('pointer-events', 'none');
title.appendChild(document.createTextNode(t));
+ graph.svgtitles.appendChild(title);
return title;
};
@@ -512,7 +706,13 @@ graph.mktitle = function(t, style) {
* Return an element representing the title of a component.
*/
graph.comptitle = function(comp) {
- return graph.mktitle(graph.title(comp), graph.compstyle(comp));
+ return memo(comp, 'title', function() {
+ var ct = graph.title(comp);
+ var pt = graph.propertytitle(comp);
+ if (ct == '' && pt == '')
+ return null;
+ return graph.mktitle((ct != '' && pt != '')? ct + ' ' + pt : ct + pt, titlex, titley);
+ });
};
/**
@@ -520,78 +720,81 @@ graph.comptitle = function(comp) {
*/
graph.comptitlewidth = function(comp) {
var title = graph.comptitle(comp);
- graph.titlewidthsvg.appendChild(title);
- var width = title.getBBox().width + 2;
- graph.titlewidthsvg.removeChild(title);
- return width;
+ if (isNil(title))
+ return 0;
+ return title.getBBox().width + titlew;
};
/**
- * Return an element representing the title of a reference.
+ * Draw a component shape selection.
*/
-graph.reftitle = function(ref) {
- return graph.mktitle(graph.title(ref), graph.refstyle(ref));
-};
+graph.compselect = function(g, s, cvalue, ccopy, cdelete) {
+ if (isNil(g) || !s) {
+ cvalue.value = '';
+ cvalue.disabled = true;
+ ccopy.disabled = true;
+ cdelete.disabled = true;
+ if (isNil(g))
+ return true;
+ g.shape.setAttribute('stroke', graph.colors.gray);
+ g.shape.setAttribute('stroke-width', '1');
+ return true;
+ }
-/**
- * Return the width of the title of a reference.
- */
-graph.reftitlewidth = function(ref) {
- var title = graph.reftitle(ref);
- graph.titlewidthsvg.appendChild(title);
- var width = title.getBBox().width;
- graph.titlewidthsvg.removeChild(title);
- return width;
-};
+ cvalue.value = graph.hasproperty(g.comp)? graph.property(g.comp) : g.id;
+ cvalue.disabled = false;
+ ccopy.disabled = false;
+ cdelete.disabled = false;
-/**
- * Return an element representing the value of a property.
- */
-graph.proptitle = function(comp) {
- var title = graph.mktitle(graph.propertytitle(comp), graph.propstyle(comp));
- title.setAttribute('x', graph.comptitlewidth(comp) + 7);
- return title;
+ g.shape.setAttribute('stroke', graph.colors.link);
+ g.shape.setAttribute('stroke-width', '2');
+ g.parentNode.appendChild(g);
+ return true;
};
/**
- * Return the width of the title of a property.
+ * Draw a palette shape selection.
*/
-graph.proptitlewidth = function(comp) {
- var title = graph.proptitle(comp);
- graph.titlewidthsvg.appendChild(title);
- var width = title.getBBox().width + 4;
- graph.titlewidthsvg.removeChild(title);
- return width;
+graph.paletteselect = function(g, s) {
+ if (isNil(g))
+ return true;
+ if (!s) {
+ g.shape.setAttribute('stroke', graph.colors.gray);
+ g.shape.setAttribute('stroke-width', '1');
+ return true;
+ }
+
+ g.shape.setAttribute('stroke', graph.colors.link);
+ g.shape.setAttribute('stroke-width', '2');
+ g.parentNode.appendChild(g);
+ return true;
};
/**
- * Draw a component shape selection.
+ * Draw a component outline for faster rendering.
*/
-graph.compselect = function(g, s, cvalue, cdelete) {
- if (isNil(g) || !s) {
- if (!isNil(cvalue)) {
- cvalue.value = '';
- cvalue.disabled = true;
- }
- if (!isNil(cdelete))
- cdelete.disabled = true;
- if (isNil(g))
- return true;
- g.contour.setAttribute('stroke', graph.colors.gray);
- g.contour.setAttribute('stroke-opacity', '0.20');
+graph.compoutline = function(g, s) {
+ if (s == (isNil(g.outlined)? false : g.outlined))
return true;
- }
+ g.outlined = s;
- if (!isNil(cvalue)) {
- cvalue.value = graph.hasproperty(g.comp)? graph.property(g.comp) : g.id;
- cvalue.disabled = false;
+ if (s) {
+ g.shape.setAttribute('fill', 'none');
+ if (!isNil(g.title))
+ g.removeChild(g.title);
+ } else {
+ g.shape.setAttribute('fill', graph.color(g.comp));
+ if (!isNil(g.title))
+ g.appendChild(g.title);
}
- if (!isNil(cdelete))
- cdelete.disabled = false;
- g.contour.setAttribute('stroke', graph.colors.link);
- g.contour.setAttribute('stroke-opacity', '0.80');
- g.parentNode.appendChild(g);
+ map(function(r) {
+ var n = caddr(r);
+ if (isNil(n))
+ return r;
+ graph.compoutline(n, s);
+ return r;
+ }, g.refpos);
return true;
};
@@ -600,47 +803,38 @@ graph.compselect = function(g, s, cvalue, cdelete) {
*/
graph.compnode = function(comp, cassoc, pos, parentg) {
- // Make the component and property title elements
+ // Make the component title element
var title = graph.comptitle(comp);
- var prop = graph.proptitle(comp);
// Compute the path of the component shape
var path = graph.comppath(comp, cassoc);
- var d = path.str();
// Create the main component shape
var shape = document.createElementNS(graph.svgns, 'path');
- shape.setAttribute('d', d);
+ shape.setAttribute('d', path.str());
shape.setAttribute('fill', graph.color(comp));
- shape.setAttribute('fill-opacity', '0.60');
-
- // Create an overlay contour shape
- var contour = document.createElementNS(graph.svgns, 'path');
- contour.setAttribute('d', d);
- contour.setAttribute('fill', 'none');
- contour.setAttribute('stroke', graph.colors.gray);
- contour.setAttribute('stroke-width', '3');
- contour.setAttribute('stroke-opacity', '0.20');
- contour.setAttribute('transform', 'translate(1,1)');
-
- // Create a group and add the component and contour shapes to it.
+ //shape.setAttribute('fill-opacity', '0.6');
+ shape.setAttribute('stroke', graph.colors.gray);
+ shape.setAttribute('stroke-width', '1');
+ shape.setAttribute('pointer-events', 'visible');
+
+ // Create an svg group and add the shape and title to it
var g = document.createElementNS(graph.svgns, 'g');
+ g.comp = comp;
g.id = scdl.name(comp);
g.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')');
+ g.pos = pos.clone();
g.appendChild(shape);
- g.appendChild(contour);
- g.appendChild(title);
- g.appendChild(prop);
+ g.shape = shape;
+ if (!isNil(title)) {
+ g.appendChild(title);
+ g.title = title;
+ }
- // Store the component and the positions of its services
- // and references in the component shape
- g.comp = comp;
+ // Store the the positions of the services and references
g.refpos = reverse(path.refpos);
g.svcpos = reverse(path.svcpos);
- // Store the contour in the component shape
- g.contour = contour;
-
// Handle onclick events
g.onclick = parentg.onclick;
@@ -669,6 +863,7 @@ graph.findcompnode = function(name, nodes) {
graph.mkgroup = function(pos) {
var g = document.createElementNS(graph.svgns, 'g');
g.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')');
+ g.pos = pos.clone();
return g;
};
@@ -678,7 +873,7 @@ graph.mkgroup = function(pos) {
graph.mkbutton = function(t, pos) {
// Make the button title
- var title = graph.mktitle(t, '');
+ var title = graph.mktitle(t, titlex, titley);
// Compute the path of the button shape
var path = graph.buttonpath().str();
@@ -686,27 +881,21 @@ graph.mkbutton = function(t, pos) {
// Create the main button shape
var shape = document.createElementNS(graph.svgns, 'path');
shape.setAttribute('d', path);
- shape.setAttribute('fill', graph.colors.lightgray);
- shape.setAttribute('fill-opacity', '0.60');
-
- // Create an overlay contour shape
- var contour = document.createElementNS(graph.svgns, 'path');
- contour.setAttribute('d', path);
- contour.setAttribute('fill', 'none');
- contour.setAttribute('stroke', graph.colors.gray);
- contour.setAttribute('stroke-width', '3');
- contour.setAttribute('stroke-opacity', '0.20');
- contour.setAttribute('transform', 'translate(1,1)');
-
- // Create a group and add the button and contour shapes to it
+ shape.setAttribute('fill', graph.colors.lightgray1);
+ //shape.setAttribute('fill-opacity', '0.6');
+ shape.setAttribute('stroke', graph.colors.gray);
+ shape.setAttribute('stroke-width', '1');
+ shape.setAttribute('pointer-events', 'visible');
+
+ // Create a group and add the button shape to it
var g = document.createElementNS(graph.svgns, 'g');
g.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')');
+ g.pos = pos.clone();
g.appendChild(shape);
- g.appendChild(contour);
g.appendChild(title);
- // Store the contour in the button shape
- g.contour = contour;
+ // Store the button shape in the group
+ g.shape = shape;
return g;
};
@@ -719,7 +908,7 @@ graph.relpos = function(e) {
var matrix = e.getCTM();
var curX = pmatrix != null? (Number(matrix.e) - Number(pmatrix.e)): Number(matrix.e);
var curY = pmatrix != null? (Number(matrix.f) - Number(pmatrix.f)): Number(matrix.f);
- return graph.mkpath().move(curX, curY);
+ return graph.mkpath().pos(curX, curY);
};
/**
@@ -727,6 +916,7 @@ graph.relpos = function(e) {
*/
graph.move = function(e, pos) {
e.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')');
+ e.pos = pos.clone();
};
/**
@@ -737,7 +927,7 @@ graph.abspos = function(e, g) {
return graph.mkpath();
var gpos = graph.relpos(e);
var pgpos = graph.abspos(e.parentNode, g);
- return graph.mkpath().move(gpos.xpos() + pgpos.xpos(), gpos.ypos() + pgpos.ypos());
+ return graph.mkpath().pos(gpos.xpos() + pgpos.xpos(), gpos.ypos() + pgpos.ypos());
};
/**
@@ -770,14 +960,6 @@ graph.title = function(e) {
};
/**
- * Return the display style of an SCDL component or reference.
- */
-graph.compstyle = graph.refstyle = function(e) {
- var s = scdl.style(e);
- return isNil(s)? '' : s;
-};
-
-/**
* Return the property value of a SCDL component.
*/
graph.property = function(e) {
@@ -814,19 +996,6 @@ graph.hasproperty = function(e) {
};
/**
- * Return the display style of the property of an SCDL component.
- */
-graph.propstyle = function(e) {
- var p = scdl.properties(e);
- if (isNil(p))
- return '';
- if (scdl.visible(car(p)) == 'false')
- return '';
- var s = scdl.style(car(p));
- return isNil(s)? '' : s;
-};
-
-/**
* Change the property value of a SCDL component.
*/
graph.setproperty = function(e, value) {
@@ -851,19 +1020,6 @@ graph.color = function(comp) {
};
/**
- * Return the services on the top side of a component.
- */
-graph.tsvcs = function(comp) {
- return memo(comp, 'tsvcs', function() {
- var svcs = scdl.services(comp);
- var l = filter(function(s) { return scdl.align(s) == 'top' && scdl.visible(s) != 'false'; }, svcs);
- if (isNil(l))
- return mklist();
- return mklist(car(l));
- });
-};
-
-/**
* Return the services on the left side of a component.
*/
graph.lsvcs = function(comp) {
@@ -878,22 +1034,11 @@ graph.lsvcs = function(comp) {
}, svcs);
if (isNil(l))
return mklist();
- if (!isNil(graph.tsvcs(comp)))
- return mklist();
return mklist(car(l));
});
};
/**
- * Return the references on the bottom side of a component.
- */
-graph.brefs = function(comp) {
- return memo(comp, 'brefs', function() {
- return filter(function(r) { return scdl.align(r) == 'bottom' && scdl.visible(r) != 'false'; }, scdl.references(comp));
- });
-};
-
-/**
* Return the references on the right side of a component.
*/
graph.rrefs = function(comp) {
@@ -913,19 +1058,7 @@ graph.rrefheight = function(ref, cassoc) {
return memo(ref, 'rheight', function() {
var target = assoc(scdl.target(ref), cassoc);
if (isNil(target))
- return tabsz * 10;
- return graph.compclosureheight(cadr(target), cassoc);
- });
-};
-
-/**
- * Return the height of a reference on the bottom side of a component.
- */
-graph.brefheight = function(ref, cassoc) {
- return memo(ref, 'bheight', function() {
- var target = assoc(scdl.target(ref), cassoc);
- if (isNil(target))
- return 0;
+ return tabsz * 8;
return graph.compclosureheight(cadr(target), cassoc);
});
};
@@ -940,27 +1073,15 @@ graph.rrefsheight = function(refs, cassoc) {
};
/**
- * Return the max height of the references on the bottom side of a component.
- */
-graph.brefsheight = function(refs, cassoc) {
- if (isNil(refs))
- return 0;
- return Math.max(graph.brefheight(car(refs), cassoc), graph.brefsheight(cdr(refs), cassoc));
-};
-
-/**
* Return the height of a component node.
*/
graph.compheight = function(comp, cassoc) {
return memo(comp, 'height', function() {
var lsvcs = graph.lsvcs(comp);
- var lsvcsh = Math.max(1, length(lsvcs)) * (tabsz * 10) + (tabsz * 4);
+ var lsvcsh = Math.max(1, length(lsvcs)) * (tabsz * 8) + (tabsz * 4);
var rrefs = graph.rrefs(comp);
- var rrefsh = graph.rrefsheight(rrefs, cassoc) + (tabsz * 4);
- var height = Math.max(lsvcsh, rrefsh);
- if (!isNil(graph.brefs(comp)))
- height = Math.max(height, (tabsz * 10) + (tabsz * 4) + (tabsz * 2));
- return height;
+ var rrefsh = graph.rrefsheight(rrefs, cassoc) + (tabsz * 2);
+ return Math.max(lsvcsh, rrefsh);
});
};
@@ -969,40 +1090,17 @@ graph.compheight = function(comp, cassoc) {
*/
graph.compclosureheight = function(comp, cassoc) {
return memo(comp, 'closureheight', function() {
- var brefs = graph.brefs(comp);
- var height = graph.compheight(comp, cassoc) + graph.brefsheight(brefs, cassoc);
- return height;
+ return graph.compheight(comp, cassoc);
});
};
/**
- * Return the width of a reference on the bottom side of a component.
- */
-graph.brefwidth = function(ref, cassoc) {
- return memo(ref, 'width', function() {
- var target = assoc(scdl.target(ref), cassoc);
- if (isNil(target))
- return tabsz * 10;
- return graph.compclosurewidth(cadr(target), cassoc);
- });
-};
-
-/**
- * Return the total width of the references on the bottom side of a component.
- */
-graph.brefswidth = function(refs, cassoc) {
- if (isNil(refs))
- return 0;
- return graph.brefwidth(car(refs), cassoc) + graph.brefswidth(cdr(refs), cassoc);
-};
-
-/**
* Return the max width of the references on the right side of a component.
*/
graph.rrefswidth = function(refs, cassoc) {
if (isNil(refs))
return 0;
- return Math.max(graph.brefwidth(car(refs), cassoc), graph.rrefswidth(cdr(refs), cassoc));
+ return Math.max(graph.rrefwidth(car(refs), cassoc), graph.rrefswidth(cdr(refs), cassoc));
};
/**
@@ -1010,23 +1108,10 @@ graph.rrefswidth = function(refs, cassoc) {
*/
graph.compwidth = function(comp, cassoc) {
return memo(comp, 'width', function() {
- var twidth = graph.comptitlewidth(comp) + graph.proptitlewidth(comp) + (tabsz * 8);
- var tsvcs = graph.tsvcs(comp);
- var tsvcsw = Math.max(1, length(tsvcs)) * (tabsz * 10) + (tabsz * 4);
- var brefs = graph.brefs(comp);
- var brefsw = graph.brefswidth(brefs, cassoc) + (tabsz * 4);
- var width = Math.max(twidth, Math.max(tsvcsw, brefsw));
- return width;
- });
-};
-
-/**
- * Return the width of a component and all the components wired to its right side.
- */
-graph.compclosurewidth = function(comp, cassoc) {
- return memo(comp, 'closurewidth', function() {
- var rrefs = graph.rrefs(comp);
- var width = graph.compwidth(comp, cassoc) + graph.rrefswidth(rrefs, cassoc);
+ var ctw = graph.comptitlewidth(comp);
+ var rrefsw = (isNil(graph.rrefs(comp))? 0 : (tabsz * 4));
+ var twidth = (titlex * 2) + ctw + rrefsw;
+ var width = Math.max(twidth, (tabsz * 8) + (tabsz * 4));
return width;
});
};
@@ -1034,62 +1119,31 @@ graph.compclosurewidth = function(comp, cassoc) {
/**
* Return a path representing a reference positioned to the right of a component.
*/
-graph.rrefpath = function(ref, cassoc, path) {
+graph.rrefpath = function(ref, cassoc, path, maxheight) {
var height = graph.rrefheight(ref, cassoc);
// Record reference position in the path
var xpos = path.xpos();
var ypos = path.ypos();
- //path.refpos = cons(mklist(ref, graph.mkpath().move(xpos, ypos + (tabsz * 6))), path.refpos);
- path.refpos = cons(mklist(ref, graph.mkpath().move(xpos, ypos + (tabsz * 5))), path.refpos);
-
- // Compute the reference path
- return path.rline(0,tabsz).rline(0,tabsz * 2).rcurve(0,tabsz,-tabsz,0).rcurve(-tabsz,0,0,-tabsz).rcurve(0,-tabsz,-tabsz,0).rcurve(-tabsz,0,0,tabsz).rline(0,tabsz * 4).rcurve(0,tabsz,tabsz,0).rcurve(tabsz,0,0,-tabsz).rcurve(0,-tabsz,tabsz,0).rcurve(tabsz,0,0,tabsz).line(path.xpos(),ypos + height);
-};
-
-/**
- * Return a path representing a reference positioned at the bottom of a component.
- */
-graph.brefpath = function(ref, cassoc, path) {
- var width = graph.brefwidth(ref, cassoc);
-
- // Record reference position in the path
- var xpos = path.xpos();
- var ypos = path.ypos();
- path.refpos = cons(mklist(ref, graph.mkpath().move(xpos - width + tabsz * 5, ypos)), path.refpos);
+ path.refpos = cons(mklist(ref, graph.mkpath().pos(xpos, ypos + (tabsz * 5))), path.refpos);
// Compute the reference path
- return path.line(xpos - width + (tabsz * 10),path.ypos()).rline(-tabsz,0).rline(-(tabsz *2),0).rcurve(-tabsz,0,0,-tabsz).rcurve(0,-tabsz,tabsz,0).rcurve(tabsz,0,0,-tabsz).rcurve(0,-tabsz,-tabsz,0).rline(-(tabsz * 4),0).rcurve(-tabsz,0,0,tabsz).rcurve(0,tabsz,tabsz,0).rcurve(tabsz,0,0,tabsz).rcurve(0,tabsz,-tabsz,0).line(xpos - width,path.ypos());
+ return path.rline(0,tabsz * 2).rcurve(0,tabsz,-tabsz,0).rcurve(-tabsz,0,0,-tabsz/2.0).rcurve(0,-tabsz/2.0,-tabsz,0).rcurve(-tabsz,0,0,tabsz/2.0).rline(0,tabsz * 3).rcurve(0,tabsz/2.0,tabsz,0).rcurve(tabsz,0,0,-tabsz/2.0).rcurve(0,-tabsz/2.0,tabsz,0).rcurve(tabsz,0,0,tabsz).line(path.xpos(), Math.min(ypos + height, maxheight));
};
/**
* Return a path representing a service positioned to the left of a component.
*/
-graph.lsvcpath = function(svc, cassoc, path) {
- var height = tabsz * 10;
-
- // Record service position in the path
- var xpos = path.xpos();
- var ypos = path.ypos();
- path.svcpos = cons(mklist(svc, graph.mkpath().move(xpos, ypos - (tabsz * 6))), path.svcpos);
-
- // Compute the service path
- return path.rline(0,-tabsz).rline(0, -(tabsz * 2)).rcurve(0,-tabsz,-tabsz,0).rcurve(-tabsz,0,0,tabsz).rcurve(0,tabsz,-tabsz,0).rcurve(-tabsz,0,0,-tabsz).rline(0,-(tabsz * 4)).rcurve(0,-tabsz,tabsz,0).rcurve(tabsz,0,0,tabsz).rcurve(0,tabsz,tabsz,0).rcurve(tabsz,0,0,-tabsz).line(path.xpos(), ypos - height);
-};
-
-/**
- * Return a path representing a service positioned at the top of a component.
- */
-graph.tsvcpath = function(svc, cassoc, path) {
- var width = tabsz * 10;
+graph.lsvcpath = function(svc, cassoc, path, minheight) {
+ var height = tabsz * 8;
// Record service position in the path
var xpos = path.xpos();
var ypos = path.ypos();
- path.svcpos = cons(mklist(svc, graph.mkpath().move(xpos + (tabsz * 5), ypos)), path.svcpos);
+ path.svcpos = cons(mklist(svc, graph.mkpath().pos(xpos, ypos - (tabsz * 6))), path.svcpos);
// Compute the service path
- return path.rline(tabsz,0).rline(tabsz * 2,0).rcurve(tabsz,0,0,-tabsz).rcurve(0,-tabsz,-tabsz,0).rcurve(-tabsz,0,0,-tabsz).rcurve(0,-tabsz,tabsz,0).rline(tabsz * 4,0).rcurve(tabsz,0,0,tabsz).rcurve(0,tabsz,-tabsz,0).rcurve(-tabsz,0,0,tabsz).rcurve(0,tabsz,tabsz,0).line(xpos + width,path.ypos());
+ return path.rline(0, -(tabsz * 2)).rcurve(0,-tabsz,-tabsz,0).rcurve(-tabsz,0,0,tabsz/2.0).rcurve(0,tabsz/2.0,-tabsz,0).rcurve(-tabsz,0,0,-tabsz/2.0).rline(0,-(tabsz * 3)).rcurve(0,-tabsz/2.0,tabsz,0).rcurve(tabsz,0,0,tabsz/2.0).rcurve(0,tabsz/2.0,tabsz,0).rcurve(tabsz,0,0,-tabsz).line(path.xpos(), Math.max(ypos - height, minheight));
};
/**
@@ -1104,10 +1158,10 @@ graph.comppath = function(comp, cassoc) {
/**
* Apply a path rendering function to a list of services or references.
*/
- function renderpath(x, f, cassoc, path) {
+ function renderpath(x, f, cassoc, path, height) {
if (isNil(x))
return path;
- return renderpath(cdr(x), f, cassoc, f(car(x), cassoc, path));
+ return renderpath(cdr(x), f, cassoc, f(car(x), cassoc, path, height), height);
}
var path = graph.mkpath().move(curvsz,0);
@@ -1116,26 +1170,20 @@ graph.comppath = function(comp, cassoc) {
path.refpos = mklist();
path.svcpos = mklist();
- // Render the services on the top side of the component
- var tsvcs = graph.tsvcs(comp);
- path = renderpath(tsvcs, graph.tsvcpath, cassoc, path);
-
// Render the references on the right side of the component
var rrefs = graph.rrefs(comp);
path = path.line(width - curvsz,path.ypos()).rcurve(curvsz,0,0,curvsz);
- path = renderpath(rrefs, graph.rrefpath, cassoc, path);
+ path = renderpath(rrefs, graph.rrefpath, cassoc, path, height - curvsz);
// Render the references on the bottom side of the component
- var brefs = reverse(graph.brefs(comp));
- var boffset = curvsz + graph.brefswidth(brefs, cassoc);
+ var boffset = curvsz;
path = path.line(path.xpos(),height - curvsz).rcurve(0,curvsz,curvsz * -1,0).line(boffset, path.ypos());
- path = renderpath(brefs, graph.brefpath, cassoc, path);
// Render the services on the left side of the component
var lsvcs = graph.lsvcs(comp);
- var loffset = curvsz + (length(lsvcs) * (tabsz * 10));
+ var loffset = curvsz + (length(lsvcs) * (tabsz * 8));
path = path.line(curvsz,path.ypos()).rcurve(curvsz * -1,0,0,curvsz * -1).line(path.xpos(), loffset);
- path = renderpath(lsvcs, graph.lsvcpath, cassoc, path);
+ path = renderpath(lsvcs, graph.lsvcpath, cassoc, path, curvsz);
// Close the component node path
path = path.line(0,curvsz).rcurve(0,curvsz * -1,curvsz,0);
@@ -1144,6 +1192,15 @@ graph.comppath = function(comp, cassoc) {
};
/**
+ * Return the position of a component.
+ */
+graph.comppos = function(comp, pos) {
+ var x = scdl.x(comp);
+ var y = scdl.y(comp);
+ return graph.mkpath().pos(x != null? Number(x) + palcx : pos.xpos(), y != null? Number(y) : pos.ypos());
+};
+
+/**
* Return a path representing a button node.
*/
graph.buttonpath = function(t) {
@@ -1209,38 +1266,6 @@ graph.composite = function(compos, pos, aspalette, g) {
return cons(mklist(car(refs), grefcomp), renderrrefs(cdr(refs), cassoc, rendermove(car(refs), cassoc, pos), gcomp));
}
- /**
- * Render the references on the bottom side of a component.
- */
- function renderbrefs(refs, cassoc, pos, gcomp) {
-
- /**
- * Render a reference on the bottom side of a component.
- */
- function renderbref(ref, cassoc, pos, gcomp) {
- var target = assoc(scdl.target(ref), cassoc);
- if (isNil(target))
- return null;
-
- // Render the component target of the reference
- return rendercomp(cadr(target), cassoc, pos);
- }
-
- /**
- * Move the rendering cursor to the right of a reference.
- */
- function rendermove(ref, cassoc, pos) {
- return pos.clone().rmove(graph.brefwidth(ref, cassoc), 0);
- }
-
- if (isNil(refs))
- return mklist();
-
- // Return list of (ref, comp rendering) pairs
- var grefcomp = renderbref(car(refs), cassoc, pos, gcomp);
- return cons(mklist(car(refs), grefcomp), renderbrefs(cdr(refs), cassoc, rendermove(car(refs), cassoc, pos), gcomp));
- }
-
// Compute the component shape
var gcomp = graph.compnode(comp, cassoc, pos, g);
@@ -1249,10 +1274,6 @@ graph.composite = function(compos, pos, aspalette, g) {
var rpos = graph.mkpath().rmove(graph.compwidth(comp, cassoc), 0);
var grrefs = renderrrefs(rrefs, cassoc, rpos, gcomp);
- var brefs = graph.brefs(comp);
- var bpos = graph.mkpath().rmove(0 , graph.compheight(comp, cassoc));
- var gbrefs = renderbrefs(brefs, cassoc, bpos, gcomp);
-
// Store list of (ref, pos, component rendering) triplets in the component
function refposgcomp(refpos, grefs) {
if (isNil(refpos))
@@ -1261,11 +1282,11 @@ graph.composite = function(compos, pos, aspalette, g) {
// Append component rendering to component
var gref = cadr(car(grefs));
if (gref != null)
- appendNodes(mklist(gref), gcomp);
+ gcomp.appendChild(gref);
return cons(mklist(car(car(refpos)), cadr(car(refpos)), gref), refposgcomp(cdr(refpos), cdr(grefs)));
}
- gcomp.refpos = refposgcomp(gcomp.refpos, append(grrefs, gbrefs));
+ gcomp.refpos = refposgcomp(gcomp.refpos, grrefs);
return gcomp;
}
@@ -1286,17 +1307,6 @@ graph.composite = function(compos, pos, aspalette, g) {
}
/**
- * Return the position of a component.
- */
- function comppos(comp, pos) {
- var x = scdl.x(comp);
- var y = scdl.y(comp);
- return graph.mkpath().move(
- x != null? Number(x) + palcx : pos.xpos(),
- y != null? Number(y) : (isNil(graph.tsvcs(comp))? pos.ypos() : pos.ypos() + (tabsz * 4)));
- }
-
- /**
* Move the rendering cursor down below a component.
*/
function rendermove(comp, cassoc, pos) {
@@ -1312,7 +1322,7 @@ graph.composite = function(compos, pos, aspalette, g) {
if (isNil(comp))
return renderproms(cdr(svcs), cassoc, rendermove(car(svcs), cassoc, pos));
- var cpos = comppos(comp, pos);
+ var cpos = graph.comppos(comp, pos);
return cons(rendercomp(comp, cassoc, cpos), renderproms(cdr(svcs), cassoc, rendermove(comp, cassoc, cpos)));
}
@@ -1325,8 +1335,8 @@ graph.composite = function(compos, pos, aspalette, g) {
// move them to the palette area
return map(function(r) {
r.id = 'palette:' + r.id;
- var gpos = graph.relpos(r);
- graph.move(r, graph.mkpath().move(gpos.xpos() - palcx, gpos.ypos()));
+ var gpos = r.pos;
+ graph.move(r, graph.mkpath().pos(gpos.xpos() - palcx, gpos.ypos()));
return r;
}, rproms);
@@ -1340,10 +1350,10 @@ graph.composite = function(compos, pos, aspalette, g) {
/**
* Return a component unique id.
*/
-graph.ucid = function(prefix, compos, clone) {
+graph.ucid = function(prefix, compos1, compos2, clone) {
// Build an assoc list keyed by component name
- var comps = map(function(c) { return mklist(scdl.name(c), c); }, namedElementChildren("'component", compos));
+ var comps = map(function(c) { return mklist(scdl.name(c), c); }, append(namedElementChildren("'component", compos1), namedElementChildren("'component", compos2)));
if (!clone && isNil(assoc(prefix, comps)))
return prefix;
@@ -1357,7 +1367,16 @@ graph.ucid = function(prefix, compos, clone) {
return ucid(p, id + 1);
}
- return ucid(prefix == ''? 'comp' : prefix, 1);
+ /**
+ * Remove trailing digits from a prefix.
+ */
+ function untrail(p) {
+ if (p.length < 2 || p[p.length - 1] < '0' || p[p.length - 1] > '9')
+ return p;
+ return untrail(p.substring(0, p.length - 1));
+ }
+
+ return ucid(prefix == ''? 'comp' : (clone? untrail(prefix) : prefix), 1);
};
/**
@@ -1365,19 +1384,17 @@ graph.ucid = function(prefix, compos, clone) {
*/
graph.clonepalette = function(e, compos, g) {
- // Clone the SCDL component and give it a unique name
- var wcomp = append(mklist(element, "'component", mklist(attribute, "'name", graph.ucid(scdl.name(e.comp), compos, true))),
+ // Clone the SCDL component and give it a unique name
+ var wcomp = append(mklist(element, "'component", mklist(attribute, "'name", graph.ucid(scdl.name(e.comp), compos, compos, true))),
filter(function(c) { return !(isAttribute(c) && attributeName(c) == "'name")}, elementChildren(e.comp)));
var x = '<composite>' + writeXML(mklist(wcomp), false) + '</composite>';
- var rcompos = readXML(mklist(x));
- var comp = car(scdl.components(rcompos));
+ var rcompos = scdl.composite(readXML(mklist(x)));
+ var comp = car(scdl.components(mklist(rcompos)));
- // Make a component node
- var gcomp = graph.compnode(comp, mklist(), graph.mkpath(), g);
- graph.move(gcomp, graph.relpos(e));
- e.parentNode.appendChild(gcomp);
+ // Update component position
+ setElement(comp, graph.movecomp(comp, graph.abspos(e, g).rmove(palcx, 0)));
- return gcomp;
+ return comp;
};
/**
@@ -1399,6 +1416,54 @@ graph.gridsnap = function(x) {
}
/**
+ * Clone a component node and all the components it references.
+ */
+graph.clonecomp = function(e, compos, g) {
+
+ // Write the component and the components it references to XML
+ function collectcomp(e) {
+ function collectrefs(refpos) {
+ if (isNil(refpos))
+ return mklist();
+ var r = car(refpos);
+ var n = caddr(r);
+ if (isNil(n))
+ return collectrefs(cdr(refpos));
+ return append(collectcomp(n), collectrefs(cdr(refpos)));
+ }
+
+ return cons(e.comp, collectrefs(e.refpos));
+ }
+
+ var allcomps = collectcomp(e);
+ var ls = map(function(e) { return writeXML(mklist(e), false); }, allcomps);
+ var x = '<composite>' + writeStrings(ls) + '</composite>';
+
+ // Read them back from XML to clone them
+ var rcompos = scdl.composite(readXML(mklist(x)));
+ var comps = scdl.components(mklist(rcompos));
+
+ // Give them new unique names
+ map(function(e) {
+
+ // Rename each component
+ var oname = scdl.name(e);
+ var name = graph.ucid(oname, compos, rcompos, true);
+ setElement(e, append(mklist(element, "'component", mklist(attribute, "'name", name)),
+ filter(function(c) { return !(isAttribute(c) && attributeName(c) == "'name")}, elementChildren(e))));
+
+ // Refactor references to the component
+ map(function(c) { return graph.refactorrefs(scdl.references(c), oname, name); }, comps);
+ }, comps);
+
+ // Update the top component position
+ var comp = car(comps);
+ setElement(comp, graph.movecomp(comp, graph.abspos(e, g).rmove(10, 10)));
+
+ return comps;
+};
+
+/**
* Sort elements of a composite.
*/
graph.sortcompos = function(compos) {
@@ -1431,12 +1496,14 @@ graph.sortcompos = function(compos) {
}
/**
- * Add a component to a SCDL composite.
+ * Add a list of components to a SCDL composite. The first
+ * component in the list is a promoted component.
*/
-graph.addcomp = function(comp, compos) {
+graph.addcomps = function(comps, compos) {
+ var comp = car(comps);
var name = scdl.name(comp);
var prom = mklist(element, "'service", mklist(attribute, "'name", name), mklist(attribute, "'promote", name));
- return append(mklist(element, "'composite"), append(elementChildren(compos), mklist(prom, comp)));
+ return append(mklist(element, "'composite"), append(elementChildren(compos), cons(prom, comps)));
};
/**
@@ -1495,31 +1562,31 @@ graph.clonerefs = function(compos) {
}
/**
- * Rename a component.
+ * Refactor references to a component.
*/
-graph.renamecomp = function(comp, compos, name) {
+graph.refactorrefs = function(refs, oname, nname) {
+ if (isNil(refs))
+ return true;
+ var ref = car(refs);
+ if (scdl.target(ref) != oname)
+ return graph.refactorrefs(cdr(refs), oname, nname);
- /**
- * Refactor references to a component.
- */
- function refactorrefs(refs, oname, nname) {
- if (isNil(refs))
- return true;
- var ref = car(refs);
- if (scdl.target(ref) != oname)
- return refactorrefs(cdr(refs), oname, nname);
+ // Change the reference's target attribute
+ setElement(ref, append(mklist(element, "'reference"),
+ append(filter(function(e) { return !(isAttribute(e) && attributeName(e) == "'target"); }, elementChildren(ref)),
+ mklist(mklist(attribute, "'target", nname)))));
- // Change the reference's target attribute
- setElement(ref, append(mklist(element, "'reference"),
- append(filter(function(e) { return !(isAttribute(e) && attributeName(e) == "'target"); }, elementChildren(ref)),
- mklist(mklist(attribute, "'target", nname)))));
+ return graph.refactorrefs(cdr(refs), oname, nname);
+};
- return refactorrefs(cdr(refs), oname, nname);
- }
+/**
+ * Rename a component.
+ */
+graph.renamecomp = function(comp, compos, name) {
// Refactor all the references to the renamed component
var oname = scdl.name(comp);
- map(function(c) { return refactorrefs(scdl.references(c), oname, name); }, namedElementChildren("'component", compos));
+ map(function(c) { return graph.refactorrefs(scdl.references(c), oname, name); }, namedElementChildren("'component", compos));
// Rename the SCDL promoted service and component
var proms = filter(function(s) { return scdl.name(s) == oname }, scdl.services(compos));
@@ -1645,10 +1712,13 @@ graph.wire = function(n, compos, g) {
/**
* Display a list of graphical nodes.
*/
-graph.display = function(nodes, g) {
+graph.display = function(nodes, g, svg) {
+ var suspend = svg.suspendRedraw(10);
// Append the nodes to the graphical canvas
appendNodes(nodes, g);
+
+ svg.unsuspendRedraw(suspend);
return nodes;
};
@@ -1666,12 +1736,15 @@ graph.hide = function(g) {
* Refresh a graph.
*/
graph.refresh = function(g) {
+ //log('refresh');
// Remove existing nodes from the graph
map(function(n) { if (!isNil(n.comp) && n.id.substr(0, 8) != 'palette:') { g.removeChild(n); } return n; }, nodeList(g.childNodes));
// Redisplay the composite associated with the graph
- return graph.display(graph.composite(g.compos, graph.mkpath().move(palcx,0), false, g), g);
+ var nodes = graph.composite(g.compos, graph.mkpath().pos(palcx,0), false, g);
+ appendNodes(nodes, g);
+ return nodes;
};
/**
@@ -1679,6 +1752,7 @@ graph.refresh = function(g) {
* nodes that represent it.
*/
graph.edit = function(appname, compos, nodes, onchange, onselect, g) {
+ var suspend = g.suspendRedraw(10);
// Store the appname and composite in the graphical canvas
g.appname = appname;
@@ -1692,7 +1766,13 @@ graph.edit = function(appname, compos, nodes, onchange, onselect, g) {
g.oncomposchange = onchange;
g.oncompselect = onselect;
+ // Remove existing nodes from the graph
+ map(function(n) { if (!isNil(n.comp) && n.id.substr(0, 8) != 'palette:') { g.removeChild(n); } return n; }, nodeList(g.childNodes));
+
// Display the composite nodes
- return graph.display(nodes, g);
+ appendNodes(nodes, g);
+
+ g.unsuspendRedraw(suspend);
+ return nodes;
};
diff --git a/sca-cpp/trunk/modules/edit/htdocs/graph/index.html b/sca-cpp/trunk/modules/edit/htdocs/graph/index.html
index aea21acf1e..6e93548814 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/graph/index.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/graph/index.html
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html>
+<html manifest="/cache-manifest.cmf">
<head>
<title></title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
@@ -29,49 +29,65 @@
<script type="text/javascript" src="/menu.js"></script>
<script type="text/javascript" src="graph.js"></script>
</head>
-<body class="delayed" onload="ui.onload();">
-<div id="bodydiv" class="devicewidth">
+<body class="delayed" onload="ui.onload();" onbeforeunload="ui.onbeforeunload();">
+<div id="bodydiv" class="bodydiv" style="overflow: visible;">
<div id="headdiv" class="hsection">
<script type="text/javascript" src="/headconfig.js"></script>
</div>
+<div id="menubackground" style="position: absolute; top: 0px; left: 0px; z-index: -1; width: 2500px;">
+<table cellpadding="0" cellspacing="0" width="100%" class="tbar"><tr><td class="dtbar">
+<table border="0" cellspacing="0" cellpadding="0"><tr><td class="ltbar"><span class="tbarsmenu">>&nbsp</span></td></tr></table>
+</td></tr></table>
+</div>
+
<div id="menu"></div>
<table style="width: 100%;">
<tr>
-<td><h2><span id="h1"></span><span id="appNameHeader"></span></h2></td>
-<td style="vertical-align: middle; text-align: right; padding-right: 2px;"><span id="saveStatus" style="font-weight: bold; color: #808080;">Saved</span></td>
+<td><h2><span id="appNameHeader"></span></h2></td>
+<td style="vertical-align: middle; text-align: right; padding-right: 8px;"><span id="saveStatus" style="font-weight: bold; color: #808080;">Saved</span></td>
</tr>
</table>
-<table style="width: 100%;">
+<table id="compValueBackground" style="width: 2500px; position: absolute; top: 59px; left: 0px; z-index: -1;">
<tr>
-<th class="thr thl" style="padding-left: 2px; padding-right: 2px; width: 100%">
+<th class="thr thl"><span style="display: inline-block; padding-top: 0px; padding-bottom: 0px; height: 24px;"></span></th>
+</tr>
+</table>
+
+<table id="compValueTable" style="width: 100%;">
+<tr>
+<td class="thr thl" style="padding-left: 2px; padding-right: 2px; vertical-align: top; width: 100%">
<input id="compValue" type="text" value="" title="Component value" autocapitalize="off" placeholder="Value" style="position: relative; width: 100%;"/>
-</th>
+</td>
-<th class="thl thr" style="text-align: right; padding-right: 2px;">
-<span id="deleteCompButton" title="Delete a component" class="redbutton" style="font-weight: bold; font-size: 16px; color: #808080; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">-</span>
+<td class="thl thr" style="text-align: right; padding-right: 2px; vertical-align: top;">
+<span id="deleteCompButton" title="Delete a component" class="graybutton" style="font-weight: bold; font-size: 16px; color: #808080; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; text-align: center; margin-left: 0px; margin-right: 0px;">-</span>
-<span id="addCompButton" title="Add a component" class="greenbutton" style="font-weight: bold; font-size: 16px; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">+</span>
+<span id="copyCompButton" title="Copy a component" class="graybutton" style="font-weight: bold; font-size: 16px; color: #808080; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; text-align: center; margin-left: 0px; margin-right: 0px;">c</span>
-<span id="playCompButton" title="View component value" class="bluebutton" style="font-weight: bold; font-size: 16px; color: #808080; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">&gt;</span>
-</th>
+<span id="addCompButton" title="Add a component" class="graybutton" style="font-weight: bold; font-size: 16px; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; text-align: center; margin-left: 0px; margin-right: 0px;">+</span>
+
+<span id="playCompButton" title="View component value" class="graybutton" style="font-weight: bold; font-size: 16px; color: #808080; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; text-align: center; margin-left: 0px; margin-right: 0px;">&gt;</span>
+</td>
</tr>
</table>
-<div id="contentdiv" style="margin-top: 4px; width: 100%;">
-<div id="playdiv" style="position:relative; top: 0x; left: 0px; right: 0px; height: 5000px; visibility: hidden">
+<div id="contentdiv" style="margin-top: 4px; width: 2500px;">
+<div id="playdiv" style="position:relative; top: 0x; left: 0px; right: 0px; width: 2500px; height: 5000px; visibility: hidden">
</div>
</div>
<script type="text/javascript">
+ui.initbody();
+
// Get the app name
-var appname = ui.queryParams()['app'];
+var appname = ui.fragmentParams()['app'];
var ispalette = false;
if (isNil(appname)) {
- appname = ui.queryParams()['palette'];
+ appname = ui.fragmentParams()['palette'];
if (isNil(appname))
window.open('/', '_self');
@@ -94,8 +110,7 @@ function applink(appname) {
// Set page titles
document.title = windowtitle(window.location.hostname) + ' - ' + (isNil(config.compose)? 'Composition' : config.compose) + ' - ' + appname;
-//$('h1').innerHTML = hometitle(window.location.hostname);
-$('appNameHeader').innerHTML = '<a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '.' + window.location.hostname + '</a>';
+$('appNameHeader').innerHTML = '<a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '</a>';
// Load the menu bar
displaymenu();
@@ -106,10 +121,20 @@ displaymenu();
var cvalue = $('compValue');
var cadd = $('addCompButton');
var cdelete = $('deleteCompButton');
+var ccopy = $('copyCompButton');
var cplay = $('playCompButton');
+// Position background divs
+var mbackground = $('menubackground');
+var menudiv = $('menu');
+mbackground.style.top = ui.pixpos(menudiv.offsetTop);
+
+var cvbackground = $('compValueBackground');
+var cvtable = $('compValueTable');
+cvbackground.style.top = ui.pixpos(cvtable.offsetTop);
+
/**
- * Adjust field size.
+ * Adjust component value field size.
*/
function resizeFields() {
cvalue.style.width = '0px';
@@ -176,6 +201,11 @@ function getapp(name, g) {
if (isNil(name))
return false;
return composites.get(name, function(doc) {
+
+ // Stop now if we didn't get a composite
+ if (doc == null)
+ return false;
+
composite = atomcomposite(doc);
if (isNil(composite)) {
@@ -197,16 +227,19 @@ function getapp(name, g) {
/**
* Display a palette. Get it from the server if needed.
*/
-function displaypalette(name, g, palette, gpalettes) {
+function displaypalette(name, g, svg, palette, gpalettes) {
if (isNil(name))
return;
if (isNil(gpalettes[name])) {
// Get the palette from the server
- var doc = palettes.get(name);
- gpalettes[name] = graph.composite(atomcomposite(doc), graph.mkpath().move(2580,0), true, g);
+ palettes.get(name, function(doc) {
+ gpalettes[name] = graph.composite(atomcomposite(doc), graph.mkpath().move(2580,0), true, g);
+ graph.display(gpalettes[name], g, svg);
+ });
+ return true;
}
- graph.display(gpalettes[name], g);
+ graph.display(gpalettes[name], g, svg);
return true;
}
@@ -216,16 +249,16 @@ function displaypalette(name, g, palette, gpalettes) {
*/
function installpalette(name, pos, g, bg, palette, gpalettes) {
var b = graph.mkbutton(name, pos);
- graph.display(mklist(b), g);
+ graph.display(mklist(b), g, g);
b.onclick = function(e) {
// Swap the selected palette
- graph.compselect(bpalette, false);
- displaypalette(spalette, bg, palette, gpalettes);
+ graph.paletteselect(bpalette, false);
+ displaypalette(spalette, bg, g, palette, gpalettes);
bpalette = b;
- graph.compselect(b, true, null, null);
+ graph.paletteselect(b, true);
spalette = name;
- return displaypalette(spalette, g, palette, gpalettes);
+ return displaypalette(spalette, g, g, palette, gpalettes);
};
if (name != spalette) {
@@ -236,8 +269,8 @@ function installpalette(name, pos, g, bg, palette, gpalettes) {
}
// Display the selected palette
- graph.compselect(b, true, null, null);
- displaypalette(name, g, palette, gpalettes);
+ graph.paletteselect(b, true);
+ displaypalette(name, g, g, palette, gpalettes);
return b;
}
@@ -251,8 +284,11 @@ function save(savexml) {
var entry = '<entry xmlns="http://www.w3.org/2005/Atom">' +
'<title type="text">' + appname + '</title><id>' + appname + '</id><content type="application/xml">' +
savedcomposxml + '</content></entry>';
- composites.put(appname, entry, function(r) {
+ composites.put(appname, entry, function(e) {
+ if (e)
+ return false;
$('saveStatus').innerHTML = 'Saved';
+ return false;
});
return true;
}
@@ -293,7 +329,7 @@ function compdatalink(appname, cname) {
var port = ':' + window.location.port;
if (port == ':80' || port == ':443' || port == ':')
port = '';
- var link = protocol + '//' + appname + '.' + host + port + '/data/?component=' + cname;
+ var link = protocol + '//' + appname + '.' + host + port + '/data/#component=' + cname;
return link;
}
@@ -327,6 +363,7 @@ function oncompselect(gsel) {
}
updateButton(cdelete, link != '');
+ updateButton(ccopy, link != '');
updateButton(cplay, link != '');
return true;
}
@@ -344,7 +381,8 @@ function showdata(gcomp) {
gdiv.style.visibility = 'hidden'
gvisible = false;
pdiv.style.visibility = 'visible';
- pdiv.innerHTML = '<iframe id="dataFrame" style="position: relative; height: 5000px; width: 100%; border: 0px;" scrolling="no" frameborder="0" src="' +
+ pdiv.innerHTML = '';
+ pdiv.innerHTML = '<iframe id="dataFrame" style="position: relative; height: 5000px; width: 2500px; border: 0px;" scrolling="no" frameborder="0" src="' +
compdatalink(appname, gcomp.id) + '"></iframe>';
return true;
}
@@ -360,7 +398,7 @@ function showgraph(gcomp) {
pdiv.innerHTML = '';
gdiv.style.visibility = 'visible'
gvisible = true;
- graph.compselect(gcomp, true, cvalue, cdelete);
+ graph.compselect(gcomp, true, cvalue, ccopy, cdelete);
return true;
}
@@ -376,26 +414,26 @@ cplay.onclick = function() {
}
// Create editor graph area
-g = graph.mkgraph(cdiv, graph.mkpath().move(-2500,0), cvalue, cadd, cdelete);
+g = graph.mkgraph(cdiv, graph.mkpath().move(-2500,0), cvalue, cadd, ccopy, cdelete);
gdiv = g.parentNode;
bg = graph.mkgroup(graph.mkpath());
// Install the palettes
var pos = graph.mkpath().move(0, 0);
-bpalette = installpalette('control', pos.rmove(5,0), g, bg, spalette, gpalettes);
-installpalette('values', pos.rmove(0,35), g, bg, spalette, gpalettes);
-installpalette('lists', pos.rmove(0, 35), g, bg, spalette, gpalettes);
-installpalette('transform', pos.rmove(0, 35), g, bg, spalette, gpalettes);
-installpalette('text', pos.rmove(0, 35), g, bg, spalette, gpalettes);
-installpalette('http', pos.rmove(0, 35), g, bg, spalette, gpalettes);
-installpalette('animation', pos.rmove(0, 35), g, bg, spalette, gpalettes);
-installpalette('talk', pos.rmove(0, 35), g, bg, spalette, gpalettes);
-installpalette('social', pos.rmove(0, 35), g, bg, spalette, gpalettes);
-installpalette('search', pos.rmove(0, 35), g, bg, spalette, gpalettes);
-installpalette('database', pos.rmove(0, 35), g, bg, spalette, gpalettes);
-installpalette('logic', pos.rmove(0, 35), g, bg, spalette, gpalettes);
-installpalette('math', pos.rmove(0, 35), g, bg, spalette, gpalettes);
-installpalette('python', pos.rmove(0, 35), g, bg, spalette, gpalettes);
+bpalette = installpalette('control', pos.rmove(5,2), g, bg, spalette, gpalettes);
+installpalette('values', pos.rmove(0,28), g, bg, spalette, gpalettes);
+installpalette('lists', pos.rmove(0, 28), g, bg, spalette, gpalettes);
+installpalette('transform', pos.rmove(0, 28), g, bg, spalette, gpalettes);
+installpalette('text', pos.rmove(0, 28), g, bg, spalette, gpalettes);
+installpalette('http', pos.rmove(0, 28), g, bg, spalette, gpalettes);
+installpalette('animation', pos.rmove(0, 28), g, bg, spalette, gpalettes);
+installpalette('talk', pos.rmove(0, 28), g, bg, spalette, gpalettes);
+installpalette('social', pos.rmove(0, 28), g, bg, spalette, gpalettes);
+installpalette('search', pos.rmove(0, 28), g, bg, spalette, gpalettes);
+installpalette('database', pos.rmove(0, 28), g, bg, spalette, gpalettes);
+installpalette('logic', pos.rmove(0, 28), g, bg, spalette, gpalettes);
+installpalette('math', pos.rmove(0, 28), g, bg, spalette, gpalettes);
+installpalette('python', pos.rmove(0, 28), g, bg, spalette, gpalettes);
// Get and display the current app
getapp(appname, g);
diff --git a/sca-cpp/trunk/modules/edit/htdocs/index.html b/sca-cpp/trunk/modules/edit/htdocs/index.html
index 20ccc8f416..3bc871d47b 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/index.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/index.html
@@ -28,8 +28,8 @@
<script type="text/javascript" src="/all-min.js"></script>
<script type="text/javascript" src="/menu.js"></script>
</head>
-<body class="delayed" onload="ui.onload();">
-<div id="bodydiv" class="devicewidth">
+<body class="delayed" onload="ui.onload();" onbeforeunload="ui.onbeforeunload();">
+<div id="bodydiv" class="bodydiv">
<div id="headdiv" class="hsection">
<script type="text/javascript" src="/headconfig.js"></script>
@@ -46,7 +46,6 @@
<div id="maintitle" style="font-size: 150%;"></div>
<div id="maindiagram"><div id="diagram" style="width: 320px; height: 280px; background: url(home.png); padding: 0px; margin: 0px auto;"></div></div>
-<br/>
<input type="button" class="greenbutton" style="font-size: 150%; font-weight: bold; font-style: italic; padding: 10px;" id="getstarted" title="Get Started" value="Get Started"/>
@@ -56,6 +55,17 @@
</div>
<script type="text/javascript">
+
+// On mobile devices, redirect to the last visited page
+if (ui.isMobile() && (document.referrer == null || document.referrer == '')) {
+ var last = ui.lastvisited();
+ if (!isNil(last) && last != document.location)
+ window.open(last, '_self');
+}
+
+// Init and display this page
+ui.initbody();
+
// Set page titles
document.title = windowtitle(window.location.hostname);
$('h1').innerHTML = hometitle(window.location.hostname);
@@ -65,7 +75,7 @@ displaymenu();
$('maintitle').innerHTML = isNil(config.maintitle)? 'Simple App Builder' : config.maintitle;
$('getstarted').onclick = function() {
- return window.open('/store/', '_self');
+ return ui.navigate('/store/', '_self');
};
// Display the main diagram
diff --git a/sca-cpp/trunk/modules/edit/htdocs/login/index.html b/sca-cpp/trunk/modules/edit/htdocs/login/index.html
index 4c7c90cea1..e51a6ac2ae 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/login/index.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/login/index.html
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html>
+<html manifest="/cache-manifest.cmf">
<head>
<title>Sign in</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
@@ -27,8 +27,8 @@
<link rel="stylesheet" type="text/css" href="/ui-min.css"/>
<script type="text/javascript" src="/all-min.js"></script>
</head>
-<body class="delayed" onload="ui.onload();">
-<div id="bodydiv" class="devicewidth">
+<body class="delayed" onload="ui.onload();" onbeforeunload="ui.onbeforeunload();">
+<div id="bodydiv" class="bodydiv">
<h1>Sign in</h1>
@@ -38,12 +38,14 @@
<tr><td><input type="text" id="httpd_username" name="httpd_username" value="" size="15" autocapitalize="off" placeholder="Enter your user name" style="width: 300px;"/></td></tr>
<tr><td><b>Password:</b></td></tr>
<tr><td><input type="password" name="httpd_password" value="" size="15" placeholder="Enter your password" style="width: 300px;"/></td></tr>
-<tr><td><input type="submit" value="Sign in" class="greenbutton" style="font-weight: bold;"/></td><td></td></tr>
+<tr><td><input type="submit" value="Sign in" class="graybutton" style="font-weight: bold;"/></td><td></td></tr>
</table>
<input type="hidden" name="httpd_location" value="/"/>
</form>
<script type="text/javascript">
+ui.initbody();
+
function queryParams() {
qp = new Array();
qs = window.location.search.substring(1).split('&');
diff --git a/sca-cpp/trunk/modules/edit/htdocs/logout/index.html b/sca-cpp/trunk/modules/edit/htdocs/logout/index.html
index 1d6079354b..c1f7a57408 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/logout/index.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/logout/index.html
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html>
+<html manifest="/cache-manifest.cmf">
<head>
<title>Sign out</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
@@ -27,19 +27,23 @@
<link rel="stylesheet" type="text/css" href="/ui-min.css"/>
<script type="text/javascript" src="/all-min.js"></script>
</head>
-<body class="delayed" onload="ui.onload();">
-<div id="bodydiv" class="devicewidth">
+<body class="delayed" onload="ui.onload();" onbeforeunload="ui.onbeforeunload();">
+<div id="bodydiv" class="bodydiv">
<h1>Sign out</h1>
<form name="signout" onsubmit="submitSignout();" action="/" method="GET">
-<input type="submit" id="signOut" value="Sign out" class="greenbutton" style="font-weight: bold"/>
+<input type="submit" id="signOut" value="Sign out" class="graybutton" style="font-weight: bold"/>
</form>
<script type="text/javascript">
+ui.initbody();
+
function submitSignout() {
- var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE';
+ // Clear session cookie and local storage
+ var reset = 'TuscanyOpenAuth=; expires=' + new Date(1970,01,01).toGMTString() + '; domain=.' + domainname(window.location.hostname) + '; path=/; secure; version=1';
document.cookie = reset;
+ localStorage.clear();
document.signout.submit();
return true;
}
diff --git a/sca-cpp/trunk/modules/edit/htdocs/menu.js b/sca-cpp/trunk/modules/edit/htdocs/menu.js
index efddeec1dc..42f18534bc 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/menu.js
+++ b/sca-cpp/trunk/modules/edit/htdocs/menu.js
@@ -38,16 +38,16 @@ function userMenu() {
*/
function displaymenu() {
var mdiv = $('menu');
- var name = ui.queryParams()['app'];
+ var name = ui.fragmentParams()['app'];
mdiv.innerHTML = ui.menubar(
append(mklist(ui.menu('Home', '/'), ui.menu('Store', '/store/')),
(isNil(name) || name == 'undefined')?
mklist() :
mklist(
- ui.menu('Stats', '/stats/?app=' + name),
- ui.menu('Page', '/page/?app=' + name),
- ui.menu(isNil(config.compose)? 'Composition' : config.compose, '/graph/?app=' + name))),
+ ui.menu('Stats', '/stats/#app=' + name),
+ ui.menu('Page', '/page/#app=' + name),
+ ui.menu(isNil(config.compose)? 'Composition' : config.compose, '/graph/#app=' + name))),
mklist(ui.menu('Account', '/account/'), ui.menu('Sign out', '/logout/')));
}
diff --git a/sca-cpp/trunk/modules/edit/htdocs/page/index.html b/sca-cpp/trunk/modules/edit/htdocs/page/index.html
index 0102f4edac..ca2619e07b 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/page/index.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/page/index.html
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html>
+<html manifest="/cache-manifest.cmf">
<head>
<title>Page</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
@@ -29,40 +29,54 @@
<script type="text/javascript" src="/menu.js"></script>
<script type="text/javascript" src="page.js"></script>
</head>
-<body class="delayed" onload="ui.onload();">
-<div id="bodydiv" class="devicewidth">
+<body class="delayed" onload="ui.onload();" onbeforeunload="ui.onbeforeunload();">
+<div id="bodydiv" class="bodydiv" style="overflow: visible;">
<div id="headdiv" class="hsection">
<script type="text/javascript" src="/headconfig.js"></script>
</div>
+<div id="menubackground" style="position: absolute; top: 0px; left: 0px; z-index: -1; width: 2500px;">
+<table cellpadding="0" cellspacing="0" width="100%" class="tbar"><tr><td class="dtbar">
+<table border="0" cellspacing="0" cellpadding="0"><tr><td class="ltbar"><span class="tbarsmenu">&nbsp</span></td></tr></table>
+</td></tr></table>
+</div>
+
<div id="menu"></div>
<table style="width: 100%;">
<tr>
-<td><h2><span id="h1"></span><span id="appNameHeader"></span></h2></td>
-<td style="vertical-align: middle; text-align: right; padding-right: 2px;"><span id="saveStatus" style="font-weight: bold; color: #808080;">Saved</span></td>
+<td><h2><span id="appNameHeader"></span></h2></td>
+<td style="vertical-align: middle; text-align: right; padding-right: 8px;"><span id="saveStatus" style="font-weight: bold; color: #808080;">Saved</span></td>
</tr>
</table>
-<table style="width: 100%;">
+<table id="widgetValueBackground" style="width: 2500px; position: absolute; top: 59px; left: 0px; z-index: -1;">
+<tr>
+<th class="thr thl"><span style="display: inline-block; padding-top: 0px; padding-bottom: 0px; height: 24px;"></span></th>
+</tr>
+</table>
+
+<table id="widgetValueTable" style="width: 100%;">
<tr>
-<th class="thr thl" style="padding-left: 2px; padding-right: 2px; width: 100%;">
+<td class="thr thl" style="padding-left: 2px; padding-right: 2px; vertical-align: top; width: 100%;">
<input id="widgetValue" type="text" value="" title="Widget value" autocapitalize="off" placeholder="Value" style="position: relative; width: 100%;"/>
-</th>
+</td>
+
+<td class="thl thr" style="text-align: right; padding-right: 2px; vertical-align: top;">
+<span id="deleteWidgetButton" title="Delete a Widget" class="graybutton" style="font-weight: bold; font-size: 16px; color: #808080; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; text-align: center; margin-left: 0px; margin-right: 0px;">-</span>
-<th class="thl thr" style="text-align: right; padding-right: 2px;">
-<span id="deleteWidgetButton" title="Delete a Widget" class="redbutton" style="font-weight: bold; font-size: 16px; color: #808080; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">-</span>
+<span id="copyWidgetButton" title="Copy a Widget" class="graybutton" style="font-weight: bold; font-size: 16px; color: #808080; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; text-align: center; margin-left: 0px; margin-right: 0px;">c</span>
-<span id="addWidgetButton" title="Add a Widget" class="greenbutton" style="font-weight: bold; font-size: 16px; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">+</span>
+<span id="addWidgetButton" title="Add a Widget" class="graybutton" style="font-weight: bold; font-size: 16px; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; middle; text-align: center; margin-left: 0px; margin-right: 0px;">+</span>
-<span id="playPageButton" title="View page" class="bluebutton" style="font-weight: bold; font-size: 16px; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">&gt;</span>
-</th>
+<span id="playPageButton" title="View page" class="graybutton" style="font-weight: bold; font-size: 16px; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; middle; text-align: center; margin-left: 0px; margin-right: 0px;">&gt;</span>
+</td>
</tr>
</table>
-<div id="contentdiv" style="margin-top: 4px; width: 100%;">
-<div id="editdiv" style="visibility: visible; position: relative; top: 0px; left: -2500px; right: 0px; height: 5000px;">
+<div id="contentdiv" style="margin-top: 4px; width: 2500px">
+<div id="editdiv" style="visibility: visible; position: relative; top: 0px; left: -2500px; width: 2500px; height: 5000px;">
<div style="position: relative; left: 2500px; top: 0px; right: 0px; height: 5000px; border:1px; border-style: solid; border-color: #a2bae7; background: url(/public/grid72.png);"></div>
<div class="guide" style="position: absolute; left: 2500px; top: 0px; width: 320px; height: 460px;"></div>
@@ -90,15 +104,18 @@
<span class="img" id="palette:img" style="position: absolute; left: 0px; top: 430px;"><img src="/public/img.png"/></span>
</div>
-<div id="playdiv" style="visibility: hidden; position: absolute; top: 0px; left: 0px; right: 0px; height: 5000px;">
+<div id="playdiv" style="visibility: hidden; position: absolute; top: 0px; left: 0px; width: 2500px; height: 5000px;">
</div>
+
</div>
<div id="buffer" style="visibility: hidden; width: 0px; height: 0px"></div>
<script type="text/javascript">
+ui.initbody();
+
// Get the app name
-var appname = ui.queryParams()['app'];
+var appname = ui.fragmentParams()['app'];
if (isNil(appname))
window.open('/', '_self');
@@ -117,8 +134,7 @@ function applink(appname) {
// Set page titles
document.title = windowtitle(window.location.hostname) + ' - Page - ' + appname;
-//$('h1').innerHTML = hometitle(window.location.hostname);
-$('appNameHeader').innerHTML = '<a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '.' + window.location.hostname + '</a>';
+$('appNameHeader').innerHTML = '<a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '</a>';
// Load the menu bar
displaymenu();
@@ -133,6 +149,7 @@ var pdiv = $('playdiv');
var wvalue = $('widgetValue');
var wadd = $('addWidgetButton');
var wdelete = $('deleteWidgetButton');
+var wcopy = $('copyWidgetButton');
var pplay = $('playPageButton');
// Position edit and play divs inside the content div
@@ -141,8 +158,17 @@ ediv.style.top = cdiv.offsetTop + 'px';
pdiv.style.position = 'absolute';
pdiv.style.top = cdiv.offsetTop + 'px';
+// Position background divs
+var mbackground = $('menubackground');
+var menudiv = $('menu');
+mbackground.style.top = ui.pixpos(menudiv.offsetTop);
+
+var wvbackground = $('widgetValueBackground');
+var wvtable = $('widgetValueTable');
+wvbackground.style.top = ui.pixpos(wvtable.offsetTop);
+
/**
- * Adjust fields sizes.
+ * Adjust widget value field size.
*/
function resizeFields() {
wvalue.style.width = '0px';
@@ -188,6 +214,10 @@ function getpage(name, ediv) {
return false;
return pages.get(name, function(doc) {
+ // Stop now if we didn't get a page
+ if (doc == null)
+ return false;
+
// Convert the page to XHTML and place it in a hidden buffer
var buffer = $('buffer');
var el = atompage(doc);
@@ -198,7 +228,21 @@ function getpage(name, ediv) {
else
buffer.innerHTML = writeStrings(writeXML(atompage(doc), false));
- // Append page nodes to editor
+ // Remove any existing page nodes from the editor div
+ var fnodes = filter(function(e) {
+ if (isNil(e.id) || e.id == '' || e.id.substr(0, 8) == 'palette:')
+ return false;
+ var x = ui.numpos(e.style.left) - 2500;
+ if (x < 0 || ui.numpos(e.style.top) < 0)
+ return false;
+ return true;
+ }, nodeList(ediv.childNodes));
+
+ map(function(e) {
+ ediv.removeChild(e);
+ }, fnodes);
+
+ // Append new page nodes to editor
map(function(e) {
ediv.appendChild(e);
if (!isNil(e.style))
@@ -295,8 +339,11 @@ function save(newxml) {
'<title type="text">' + appname + '</title><id>' + appname + '</id><content type="application/xml">' +
newxml + '</content></entry>';
- pages.put(appname, entry, function(r) {
+ pages.put(appname, entry, function(e) {
+ if (e)
+ return false;
$('saveStatus').innerHTML = 'Saved';
+ return false;
});
return true;
};
@@ -336,7 +383,7 @@ function compvaluelink(appname, cname) {
var port = ':' + window.location.port;
if (port == ':80' || port == ':443' || port == ':')
port = '';
- var link = protocol + '//' + appname + '.' + host + port + '/data/?component=' + cname;
+ var link = protocol + '//' + appname + '.' + host + port + '/data/#component=' + cname;
return link;
}
@@ -354,6 +401,7 @@ function onwidgetselect(w) {
}
updateButton(wdelete, link != '');
+ updateButton(wcopy, link != '');
return true;
}
@@ -363,14 +411,15 @@ function onwidgetselect(w) {
function playpage() {
if (!evisible)
return true;
- page.widgetselect(widget, false, wvalue, wdelete);
+ page.widgetselect(widget, false, wvalue, wcopy, wdelete);
page.selected = null;
wvalue.value = applink(appname);
pplay.innerHTML = '&lt;';
ediv.style.visibility = 'hidden'
evisible = false;
pdiv.style.visibility = 'visible';
- pdiv.innerHTML = '<iframe id="playappframe" style="position: relative; height: 5000px; width: 100%; border: 0px;" scrolling="no" frameborder="0" src="' +
+ pdiv.innerHTML = '';
+ pdiv.innerHTML = '<iframe id="playappframe" style="position: relative; height: 5000px; width: 2500px; border: 0px;" scrolling="no" frameborder="0" src="' +
applink(appname) + '"></iframe>';
return true;
}
@@ -386,7 +435,7 @@ function showedit() {
pdiv.innerHTML = '';
ediv.style.visibility = 'visible'
evisible = true;
- page.widgetselect(widget, true, wvalue, wdelete);
+ page.widgetselect(widget, true, wvalue, wcopy, wdelete);
page.selected = widget;
return true;
}
@@ -401,7 +450,7 @@ pplay.onclick = function() {
}
// Initialize the page editor
-page.edit(ediv, wvalue, wadd, wdelete, onpagechange, onwidgetselect);
+page.edit(ediv, wvalue, wadd, wcopy, wdelete, onpagechange, onwidgetselect);
// Get and display the current app page
getpage(appname, ediv);
diff --git a/sca-cpp/trunk/modules/edit/htdocs/page/page.js b/sca-cpp/trunk/modules/edit/htdocs/page/page.js
index d316cb72dd..2fd88c0c6b 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/page/page.js
+++ b/sca-cpp/trunk/modules/edit/htdocs/page/page.js
@@ -30,12 +30,13 @@ var palcx = 2500;
/**
* Init a page editor. Works with all browsers except IE.
*/
-page.edit = function(elem, wvalue, wadd, wdelete, onchange, onselect) {
+page.edit = function(elem, wvalue, wadd, wcopy, wdelete, onchange, onselect) {
// Track element dragging and selection
page.dragging = null;
page.selected = null;
wvalue.disabled = true;
+ wcopy.disabled = true;
wdelete.disabled = true;
// Trigger widget select and page change events
@@ -59,7 +60,7 @@ page.edit = function(elem, wvalue, wadd, wdelete, onchange, onselect) {
page.dragging = dragging;
// Remember mouse position
- var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
+ var pos = typeof e.touches != "undefined"? e.touches[0] : e;
page.dragX = pos.screenX;
page.dragY = pos.screenY;
@@ -110,7 +111,7 @@ page.edit = function(elem, wvalue, wadd, wdelete, onchange, onselect) {
return true;
// Get the mouse position
- var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
+ var pos = typeof e.touches != "undefined"? e.touches[0] : e;
if (pos.screenX == page.dragX && pos.screenY == page.dragY)
return true;
@@ -150,7 +151,7 @@ page.edit = function(elem, wvalue, wadd, wdelete, onchange, onselect) {
if (page.selected != null) {
// Reset current selection
- page.widgetselect(page.selected, false, wvalue, wdelete);
+ page.widgetselect(page.selected, false, wvalue, wcopy, wdelete);
page.selected = null;
// Trigger widget select event
@@ -165,7 +166,7 @@ page.edit = function(elem, wvalue, wadd, wdelete, onchange, onselect) {
}
// Deselect the previously selected element
- page.widgetselect(page.selected, false, wvalue, wdelete);
+ page.widgetselect(page.selected, false, wvalue, wcopy, wdelete);
// Clone element dragged from palette
if (selected.id.substring(0, 8) == 'palette:') {
@@ -190,7 +191,7 @@ page.edit = function(elem, wvalue, wadd, wdelete, onchange, onselect) {
}
// Select the element
- page.widgetselect(page.selected, true, wvalue, wdelete);
+ page.widgetselect(page.selected, true, wvalue, wcopy, wdelete);
// Trigger widget select event
page.onwidgetselect(page.selected);
@@ -227,7 +228,7 @@ page.edit = function(elem, wvalue, wadd, wdelete, onchange, onselect) {
return false;
// Reset current selection
- page.widgetselect(page.selected, false, wvalue, wdelete);
+ page.widgetselect(page.selected, false, wvalue, wcopy, wdelete);
// Remove selected widget
page.selected.parentNode.removeChild(page.selected);
@@ -242,6 +243,39 @@ page.edit = function(elem, wvalue, wadd, wdelete, onchange, onselect) {
return false;
};
+ // Handle copy event.
+ wcopy.onclick = function() {
+ if (page.selected == null)
+ return false;
+ if (page.selected.id.substring(0, 8) == 'palette:')
+ return false;
+
+ // Reset current selection
+ page.widgetselect(page.selected, false, wvalue, wcopy, wdelete);
+
+ // Clone selected widget
+ page.selected = page.clone(page.selected);
+
+ // Move 10 pixels down right
+ page.selected.style.left = ui.pixpos(ui.numpos(page.selected.style.left) + 10);
+ page.selected.style.top = ui.pixpos(ui.numpos(page.selected.style.top) + 10);
+ page.selected.cover.style.left = ui.pixpos(ui.numpos(page.selected.cover.style.left) + 10);
+ page.selected.cover.style.top = ui.pixpos(ui.numpos(page.selected.cover.style.top) + 10);
+
+ // Bring it to the top
+ page.bringtotop(page.selected);
+
+ // Select the element
+ page.widgetselect(page.selected, true, wvalue, wcopy, wdelete);
+
+ // Trigger widget select event
+ page.onwidgetselect(page.selected);
+
+ // Trigger page change event
+ page.onpagechange(true);
+ return false;
+ };
+
// Cover child elements with span elements to prevent
// any input events to reach them
map(page.cover, nodeList(elem.childNodes));
@@ -253,35 +287,54 @@ page.edit = function(elem, wvalue, wadd, wdelete, onchange, onselect) {
* Return the text of a widget.
*/
page.text = function(e) {
- var formula = e.id;
- if (formula.substring(0, 5) != 'page:') {
- return '=' + formula;
+ function formula(e) {
+ var f = e.id;
+ if (f.substring(0, 5) != 'page:')
+ return '=' + f;
+ return '';
}
- if (e.className == 'h1' || e.className == 'h2' || e.className == 'text' || e.className == 'section')
- return car(childElements(e)).innerHTML;
- if (e.className == 'button' || e.className == 'checkbox')
- return car(childElements(e)).value;
- if (e.className == 'entry' || e.className == 'password')
- return car(childElements(e)).defaultValue;
- if (e.className == 'select')
- return car(childElements(car(childElements(e)))).value;
- if (e.className == 'link') {
- var hr = car(childElements(e)).href;
- var t = car(childElements(car(childElements(e)))).innerHTML;
- return hr == t? hr : hr + ',' + t;
- }
- if (e.className == 'img') {
- var src = car(childElements(e)).src;
- return src == window.location.href? '' : src;
- }
- if (e.className == 'iframe')
- return car(childElements(e)).href;
- if (e.className == 'list')
- return '';
- if (e.className == 'table')
+ function constant(e, f) {
+ if (e.className == 'h1' || e.className == 'h2' || e.className == 'text' || e.className == 'section') {
+ var t = car(childElements(e)).innerHTML;
+ return t == f? '' : t;
+ }
+ if (e.className == 'button' || e.className == 'checkbox') {
+ var t = car(childElements(e)).value;
+ return t == f? '' : t;
+ }
+ if (e.className == 'entry' || e.className == 'password') {
+ var t = car(childElements(e)).defaultValue;
+ return t == f? '' : t;
+ }
+ if (e.className == 'select') {
+ var t = car(childElements(car(childElements(e)))).value;
+ return t == f? '' : t;
+ }
+ if (e.className == 'link') {
+ var lhr = car(childElements(e)).href;
+ var hr = lhr.substring(0, 5) == 'link:'? lhr.substring(5) : '';
+ var t = car(childElements(car(childElements(e)))).innerHTML;
+ return t == f? hr : (t == hr? hr : (t == ''? hr : hr + ',' + t));
+ }
+ if (e.className == 'img') {
+ var src = car(childElements(e)).src;
+ return src == window.location.href? '' : src;
+ }
+ if (e.className == 'iframe') {
+ var hr = car(childElements(e)).href;
+ return hr == window.location.href? '' : hr;
+ }
+ if (e.className == 'list')
+ return '';
+ if (e.className == 'table')
+ return '';
return '';
- return '';
+ }
+
+ var f = formula(e);
+ var c = constant(e, f);
+ return f == ''? c : (c == ''? f : f + ',' + c);
};
/**
@@ -313,49 +366,60 @@ page.hastext = function(e) {
* Set the text of a widget.
*/
page.settext = function(e, t) {
- var formula = t.length > 1 && t.substring(0, 1) == '=';
- e.id = formula? t.substring(1) : 'page:' + e.className;
+ function formula(t) {
+ if (t.length > 1 && t.substring(0, 1) == '=')
+ return car(t.split(','));
+ return '';
+ }
+
+ function constant(t) {
+ return t.length > 1 && t.substring(0, 1) == '='? cdr(t.split(',')) : t.split(',');
+ }
+
+ var f = formula(t);
+ var c = constant(t);
+
+ e.id = f != ''? f.substring(1) : ('page:' + e.className);
if (e.className == 'h1' || e.className == 'h2' || e.className == 'text' || e.className == 'section') {
- car(childElements(e)).innerHTML = t;
+ car(childElements(e)).innerHTML = isNil(c)? f : car(c);
return t;
}
if (e.className == 'button' || e.className == 'entry' || e.className == 'password') {
- car(childElements(e)).defaultValue = t;
+ car(childElements(e)).defaultValue = isNil(c)? f : car(c);
return t;
}
if (e.className == 'checkbox') {
- car(childElements(e)).value = t;
- map(function(n) { if (n.nodeName == "SPAN") n.innerHTML = t; return n; }, nodeList(e.childNodes));
+ car(childElements(e)).value = isNil(c)? f : car(c);
+ map(function(n) { if (n.nodeName == "SPAN") n.innerHTML = isNil(c)? f : car(c); return n; }, nodeList(e.childNodes));
return t;
}
if (e.className == 'select') {
var ce = car(childElements(car(childElements(e))));
- ce.value = t;
- ce.innerHTML = t;
+ ce.value = isNil(c)? f : car(c);
+ ce.innerHTML = isNil(c)? f : car(c);
return t;
}
if (e.className == 'list') {
- e.innerHTML = '<table class="datatable" style="width: 100%;;"><tr><td class="datatd">' + t + '</td></tr><tr><td class="datatd">...</td></tr></table>';
- return '';
+ e.innerHTML = '<table class="datatable" style="width: 100%;;"><tr><td class="datatd">' + (isNil(c)? f : car(c)) + '</td></tr><tr><td class="datatd">...</td></tr></table>';
+ return t;
}
if (e.className == 'table') {
- e.innerHTML = '<table class="datatable" style="width: 100%;"><tr><td class="datatdl">' + t + '</td><td class="datatdr">...</td></tr><tr><td class="datatdl">...</td><td class="datatdr">...</td></tr></table>';
+ e.innerHTML = '<table class="datatable" style="width: 100%;"><tr><td class="datatdl">' + (isNil(c)? f : car(c)) + '</td><td class="datatdr">...</td></tr><tr><td class="datatdl">...</td><td class="datatdr">...</td></tr></table>';
return t;
}
if (e.className == 'link') {
- var l = t.split(',');
var ce = car(childElements(e));
- ce.href = car(l);
- car(childElements(ce)).innerHTML = isNil(cdr(l))? car(l) : cadr(l);
+ ce.href = isNil(c)? 'link:/index.html' : ('link:' + car(c));
+ car(childElements(ce)).innerHTML = isNil(c)? (f != ''? f : '/index.html') : isNil(cdr(c))? (f != ''? f : car(c)) : cadr(c);
return t;
}
if (e.className == 'img') {
- car(childElements(e)).src = formula? '/public/img.png' : t;
+ car(childElements(e)).src = isNil(c)? '/public/img.png' : car(c);
return t;
}
if (e.className == 'iframe') {
- car(childElements(e)).href = formula? '/public/iframe.html' : t;
+ car(childElements(e)).href = isNil(c)? '/public/iframe.html' : car(c);
return t;
}
return '';
@@ -418,11 +482,12 @@ page.bringtotop = function(n) {
/**
* Draw widget selection.
*/
-page.widgetselect = function(n, s, wvalue, wdelete) {
+page.widgetselect = function(n, s, wvalue, wcopy, wdelete) {
if (isNil(n) || !s) {
// Clear the widget value field
wvalue.value = '';
wvalue.disabled = true;
+ wcopy.disabled = true;
wdelete.disabled = true;
// Clear the widget outline
@@ -434,6 +499,7 @@ page.widgetselect = function(n, s, wvalue, wdelete) {
// Update the widget value field
wvalue.value = page.text(n);
wvalue.disabled = false;
+ wcopy.disabled = false;
wdelete.disabled = false;
// Outline the widget
diff --git a/sca-cpp/trunk/modules/edit/htdocs/public/iframe.html b/sca-cpp/trunk/modules/edit/htdocs/public/iframe.html
index 060e929dd1..a9a9efc4b3 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/public/iframe.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/public/iframe.html
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html>
+<html manifest="/cache-manifest.cmf">
<head>
<title>frame</title>
<meta name="viewport" content="width=device-width user-scalable=no initial-scale=1.0"/>
diff --git a/sca-cpp/trunk/modules/edit/htdocs/public/notauth.html b/sca-cpp/trunk/modules/edit/htdocs/public/notauth.html
index 63f9de36f4..44e68da5de 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/public/notauth.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/public/notauth.html
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html>
+<html manifest="/cache-manifest.cmf">
<head>
<title>Sorry</title>
<meta name="viewport" content="width=device-width user-scalable=no initial-scale=1.0"/>
@@ -27,8 +27,8 @@
<script type="text/javascript" src="/all-min.js"></script>
<script type="text/javascript" src="/menu.js"></script>
</head>
-<body class="delayed" onload="ui.onload();">
-<div id="bodydiv" class="devicewidth">
+<body class="delayed" onload="ui.onload();" onbeforeunload="ui.onbeforeunload();">
+<div id="bodydiv" class="bodydiv">
<div id="headdiv" class="hsection">
<script type="text/javascript" src="/headconfig.js"></script>
@@ -48,6 +48,8 @@
</form>
<script type="text/javascript">
+ui.initbody();
+
// Set page title
$('h1').innerHTML = hometitle(window.location.hostname);
diff --git a/sca-cpp/trunk/modules/edit/htdocs/public/notfound.html b/sca-cpp/trunk/modules/edit/htdocs/public/notfound.html
index 0d1ce6bb6e..c71f4aa0ef 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/public/notfound.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/public/notfound.html
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html>
+<html manifest="/cache-manifest.cmf">
<head>
<title>Page not found</title>
<meta name="viewport" content="width=device-width user-scalable=no initial-scale=1.0"/>
@@ -27,8 +27,8 @@
<script type="text/javascript" src="/all-min.js"></script>
<script type="text/javascript" src="/menu.js"></script>
</head>
-<body class="delayed" onload="ui.onload();">
-<div id="bodydiv" class="devicewidth">
+<body class="delayed">
+<div id="bodydiv" class="bodydiv" onload="ui.onload();" onbeforeunload="ui.onbeforeunload();">
<div id="headdiv" class="hsection">
<script type="text/javascript" src="/headconfig.js"></script>
@@ -46,6 +46,8 @@
</div>
<script type="text/javascript">
+ui.initbody();
+
// Set page title
$('h1').innerHTML = hometitle(window.location.hostname);
diff --git a/sca-cpp/trunk/modules/edit/htdocs/public/notyet.html b/sca-cpp/trunk/modules/edit/htdocs/public/notyet.html
index 01413549f6..591d8be991 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/public/notyet.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/public/notyet.html
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html>
+<html manifest="/cache-manifest.cmf">
<head>
<title>Page not found</title>
<meta name="viewport" content="width=device-width user-scalable=no initial-scale=1.0"/>
@@ -27,8 +27,8 @@
<script type="text/javascript" src="/all-min.js"></script>
<script type="text/javascript" src="/menu.js"></script>
</head>
-<body class="delayed" onload="ui.onload();">
-<div id="bodydiv" class="devicewidth">
+<body class="delayed" onload="ui.onload();" onbeforeunload="ui.onbeforeunload();">
+<div id="bodydiv" class="bodydiv">
<div id="headdiv" class="hsection">
<script type="text/javascript" src="/headconfig.js"></script>
@@ -45,6 +45,8 @@
</div>
<script type="text/javascript">
+ui.initbody();
+
// Set page title
$('h1').innerHTML = hometitle(window.location.hostname);
diff --git a/sca-cpp/trunk/modules/edit/htdocs/public/oops.html b/sca-cpp/trunk/modules/edit/htdocs/public/oops.html
index 5e4c638487..e85c40c172 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/public/oops.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/public/oops.html
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html>
+<html manifest="/cache-manifest.cmf">
<head>
<title>Oops</title>
<meta name="viewport" content="width=device-width user-scalable=no initial-scale=1.0"/>
@@ -27,8 +27,8 @@
<script type="text/javascript" src="/all-min.js"></script>
<script type="text/javascript" src="/menu.js"></script>
</head>
-<body class="delayed" onload="ui.onload();">
-<div id="bodydiv" class="devicewidth">
+<body class="delayed" onload="ui.onload();" onbeforeunload="ui.onbeforeunload();">
+<div id="bodydiv" class="bodydiv">
<div id="headdiv" class="hsection">
<script type="text/javascript" src="/headconfig.js"></script>
@@ -45,6 +45,8 @@
</div>
<script type="text/javascript">
+ui.initbody();
+
// Set page title
$('h1').innerHTML = hometitle(window.location.hostname);
diff --git a/sca-cpp/trunk/modules/edit/htdocs/stats/index.html b/sca-cpp/trunk/modules/edit/htdocs/stats/index.html
index a40f8b7a32..b7dd4648c6 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/stats/index.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/stats/index.html
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html>
+<html manifest="/cache-manifest.cmf">
<head>
<title>Stats</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
@@ -28,8 +28,8 @@
<script type="text/javascript" src="/all-min.js"></script>
<script type="text/javascript" src="/menu.js"></script>
</head>
-<body class="delayed" onload="ui.onload();">
-<div id="bodydiv" class="devicewidth">
+<body class="delayed" onload="ui.onload();" onbeforeunload="ui.onbeforeunload();">
+<div id="bodydiv" class="bodydiv">
<div id="headdiv" class="hsection">
<script type="text/javascript" src="/headconfig.js"></script>
@@ -49,7 +49,7 @@
<th class="thl thr" style="padding-top: 4px; padding-bottom: 4px; padding-left: 2px; padding-right: 2px; ">Stats</th>
<th class="thl thr" style="width: 100%; text-align: right; padding-right: 2px; padding-top: 0px; padding-bottom: 0px;">
-<input type="button" class="greenbutton" style="font-weight: bold; margin-top: 0px; margin-bottom: 0px; height: 24px;" id="cloneApp" value="Clone" title="Clone this app"/>
+<input type="button" class="graybutton" style="font-weight: bold; margin-top: 0px; margin-bottom: 0px; height: 24px;" id="cloneApp" value="Clone" title="Clone this app"/>
</th>
</tr>
</table>
@@ -70,8 +70,10 @@
</form>
<script type="text/javascript">
+ui.initbody();
+
// Get the app name
-var appname = ui.queryParams()['app'];
+var appname = ui.fragmentParams()['app'];
if (isNil(appname))
window.open('/', '_self');
@@ -90,8 +92,7 @@ function applink(appname) {
// Set page titles
document.title = windowtitle(window.location.hostname) + ' - Stats - ' + appname;
-//$('h1').innerHTML = hometitle(window.location.hostname);
-$('appNameHeader').innerHTML = '<a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '.' + window.location.hostname + '</a>';
+$('appNameHeader').innerHTML = '<a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '</a>';
var tclone = isNil(config.clone)? 'Clone' : config.clone;
$('cloneApp').value = tclone;
$('cloneApp').title = tclone + ' this app';
@@ -102,6 +103,7 @@ displaymenu();
// Init service references
var editWidget = sca.component("EditWidget");
var dashboards = sca.reference(editWidget, "dashboards");
+var apps = sca.reference(editWidget, "apps");
/**
* The current app entry and corresponding saved XML content.
@@ -115,7 +117,12 @@ var savedappentryxml = '';
function getapp(name) {
if (isNil(name))
return false;
- return dashboards.get(name, function(doc) {
+ return apps.get(name, function(doc) {
+
+ // Stop now if we didn't get the app
+ if (doc == null)
+ return false;
+
appentry = doc != null? car(elementsToValues(atom.readATOMEntry(mklist(doc)))) : mklist("'entry", mklist("'title", ''), mklist("'id", name));
var title = cadr(assoc("'title", cdr(appentry)));
$('appTitle').value = title;
@@ -132,8 +139,12 @@ function getapp(name) {
function save(entryxml) {
$('saveStatus').innerHTML = 'Saving';
savedappentryxml = entryxml;
- dashboards.put(appname, savedappentryxml);
- $('saveStatus').innerHTML = 'Saved';
+ dashboards.put(appname, savedappentryxml, function(e) {
+ if (e)
+ return false;
+ $('saveStatus').innerHTML = 'Saved';
+ return false;
+ });
return true;
}
@@ -165,7 +176,7 @@ $('appForm').onsubmit = function() {
* Handle Clone button event.
*/
$('cloneApp').onclick = function() {
- return window.open('/clone/?app=' + appname, '_self');
+ return ui.navigate('/clone/#app=' + appname, '_self');
}
// Get the current app
diff --git a/sca-cpp/trunk/modules/edit/htdocs/store/index.html b/sca-cpp/trunk/modules/edit/htdocs/store/index.html
index ce8b9d1251..e63dbdb834 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/store/index.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/store/index.html
@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html>
+<html manifest="/cache-manifest.cmf">
<head>
<title>Store</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
@@ -28,8 +28,8 @@
<script type="text/javascript" src="/all-min.js"></script>
<script type="text/javascript" src="/menu.js"></script>
</head>
-<body class="delayed" onload="ui.onload();">
-<div id="bodydiv" class="devicewidth">
+<body class="delayed" onload="ui.onload();" onbeforeunload="ui.onbeforeunload();">
+<div id="bodydiv" class="bodydiv">
<div id="headdiv" class="hsection">
<script type="text/javascript" src="/headconfig.js"></script>
@@ -46,6 +46,8 @@
<div id="apps"></div>
<script type="text/javascript">
+ui.initbody();
+
// Set page titles
document.title = windowtitle(window.location.hostname) + ' - Store';
$('h1').innerHTML = hometitle(window.location.hostname);
@@ -54,7 +56,7 @@ $('h1').innerHTML = hometitle(window.location.hostname);
displaymenu();
// Get the store category
-var category = ui.queryParams()['category'];
+var category = ui.fragmentParams()['category'];
if (isNil(category))
category = 'myapps';
@@ -65,10 +67,10 @@ function catmenu() {
function catmenuitem(name, cat) {
var c = cat == category? 'smenu' : 'amenu';
return '<th class="thl thr" style="width: 10px; padding-top: 4px; padding-bottom: 4px; padding-right: 6px;">'
- + ui.ahref('/store/?category=' + cat, '_self', '<span class="' + c + '">' + name + '</span>') + '</th>';
+ + ui.ahref('/store/#category=' + cat, '_reload', '<span class="' + c + '">' + name + '</span>') + '</th>';
}
- var m = '<table style="width: 100%;"><tr>';
+ var m = '<table style="width: 100%; margin-bottom: 2px;"><tr>';
m += catmenuitem('My Apps', 'myapps');
m += catmenuitem('New', 'new');
m += catmenuitem('Top', 'top');
@@ -76,7 +78,7 @@ function catmenu() {
m += catmenuitem('All', 'all');
if (category == 'myapps') {
m += '<th class="thl thr" style="width: 100%; padding-top: 0px; padding-bottom: 0px; padding-right: 0px; text-align: right;">';
- m += '<input type="button" class="greenbutton" id="createApp" title="Create a new app" style="font-weight: bold; margin-top: 0px; margin-bottom: 0px; height: 24px;" Value="New App"/>';
+ m += '<input type="button" class="graybutton" id="createApp" title="Create a new app" style="font-weight: bold; margin-top: 0px; margin-bottom: 0px; height: 24px;" Value="New App"/>';
m += '</th></tr></table>';
return m;
}
@@ -111,14 +113,14 @@ function applink(appname) {
* Edit an app.
*/
function editApp(appname) {
- return window.open('/page/?app=' + appname, '_self');
+ return ui.navigate('/page/#app=' + appname, '_self');
}
/**
* View an app.
*/
function viewApp(appname) {
- return window.open('/stats/?app=' + appname, '_self');
+ return ui.navigate('/stats/#app=' + appname, '_self');
}
/**
@@ -126,7 +128,7 @@ function viewApp(appname) {
*/
if (category == 'myapps') {
$('createApp').onclick = function() {
- return window.open('/create/', '_self');
+ return ui.navigate('/create/', '_self');
}
}
@@ -135,21 +137,29 @@ if (category == 'myapps') {
*/
function getapps(category) {
function display(doc) {
+
+ // Stop now if we didn't get the apps
+ if (doc == null)
+ return false;
+
var apps = '<div>';
var feed = car(elementsToValues(atom.readATOMFeed(mklist(doc))));
var aentries = assoc("'entry", cdr(feed));
var entries = isNil(aentries)? mklist() : isList(car(cadr(aentries)))? cadr(aentries) : mklist(cdr(aentries));
- for (var i = 0; i < length(entries); i++) {
- var entry = entries[i];
+
+ function displayentries(entries) {
+ if (isNil(entries))
+ return apps;
+ var entry = car(entries);
var title = cadr(assoc("'title", entry))
var name = cadr(assoc("'id", entry))
var author = 'joe';
var clone = isNil(config.clone)? 'Clone' : config.clone;
- apps += '<div class="box" style="width: 285px; display: inline-block; border: 1px; border-style: solid; border-color: #dcdcdc; border-collapse: collapse; margin: 5px; padding: 10px; vertical-align: top;">'
+ apps += '<div class="box" style="width: 150px; display: inline-block; border: 1px; border-style: solid; border-color: #dcdcdc; border-collapse: collapse; margin: 2px; padding: 2px; vertical-align: top;">'
apps += '<table><tr>';
apps += '<td>';
- apps += '<div>' + ui.ahref('/stats/?app=' + name, '_self', '<img src="/public/app.png" width="50" height="50" style="height: 50px; width: 50px; vertical-align: top; margin-right: 10px; margin-bottom: 5px;"></img>') + '</div>';
+ apps += '<div>' + ui.ahref('/stats/#app=' + name, '_self', '<img src="/public/app.png" width="50" height="50" style="height: 50px; width: 50px; vertical-align: top; margin: 0px; padding: 0px;"></img>') + '</div>';
apps += '</td>';
apps += '<td class="tdw">';
apps += '<div style="font-weight: bold">' + ui.ahref(applink(name), '_blank', name) + '</div>';
@@ -157,13 +167,14 @@ function getapps(category) {
apps += '<div style="color: #808080;">Shared</div>';
else
apps += '<div>' + 'by&nbsp;' + '<span style="font-weight: bold;">' + author + '</span></div>';
- apps += '<div>Feb 4, 2011</div>';
- apps += '<br/>';
- apps += '<div>' + title + '</div>';
apps += '</td>';
apps += '</tr></table>';
apps += '</div>';
+ return displayentries(cdr(entries));
}
+
+ displayentries(entries);
+
apps += '</div>';
$('apps').innerHTML = apps;
}
diff --git a/sca-cpp/trunk/modules/edit/log.py b/sca-cpp/trunk/modules/edit/log.py
index d316831db6..8aa3d3bd30 100644
--- a/sca-cpp/trunk/modules/edit/log.py
+++ b/sca-cpp/trunk/modules/edit/log.py
@@ -20,5 +20,5 @@ from sys import stderr
# Log a message
def log(msg):
- print >> stderr, msg
+ print >> stderr, '[rconsole]', msg
diff --git a/sca-cpp/trunk/modules/js/htdocs/all-min.js b/sca-cpp/trunk/modules/js/htdocs/all-min.js
index 05ae9ce35b..921abf170e 100644
--- a/sca-cpp/trunk/modules/js/htdocs/all-min.js
+++ b/sca-cpp/trunk/modules/js/htdocs/all-min.js
@@ -1,39 +1,37 @@
function cons(car,cdr){var a=new Array();a.push(car);return a.concat(cdr);}
function car(l){return l[0];}
-function first(l){return car(l);}
+function first(l){return l[0];}
function cdr(l){return l.slice(1);}
-function rest(l){return cdr(l);}
-function cadr(l){return car(cdr(l));}
-function cddr(l){return cdr(cdr(l));}
-function caddr(l){return car(cddr(l));}
-function cdddr(l){return cdr(cdr(cdr(l)));}
-function cadddr(l){return car(cdddr(l));}
+function rest(l){return l.slice(1);}
+function cadr(l){return l[1];}
+function cddr(l){return l.slice(2);}
+function caddr(l){return l[2];}
+function cdddr(l){return l.slice(3);}
+function cadddr(l){return l[3];}
function append(a,b){return a.concat(b);}
function reverse(l){return l.slice(0).reverse();}
function range(a,b){var l=new Array();for(var x=a;x<b;x++)
l.push(x);return l;}
-function isNil(v){if(v==null||typeof v=='undefined'||(v.constructor==Array&&v.length==0))
-return true;return false;}
-function isSymbol(v){if(typeof v=='string'&&v.slice(0,1)=="'")
-return true;return false;}
-function isString(v){if(typeof v=='string'&&v.slice(0,1)!="'")
-return true;return false;}
-function isList(v){if(v!=null&&typeof v!='undefined'&&v.constructor==Array)
-return true;return false;}
-function isTaggedList(v,t){if(isList(v)&&!isNil(v)&&car(v)==t)
-return true;return false;}
+function isNil(v){return(v==null||typeof v=='undefined'||(v.constructor==Array&&v.length==0));}
+function isSymbol(v){return(typeof v=='string'&&v.slice(0,1)=="'");}
+function isString(v){return(typeof v=='string'&&v.slice(0,1)!="'");}
+function isList(v){return(v!=null&&typeof v!='undefined'&&v.constructor==Array);}
+function isTaggedList(v,t){return(isList(v)&&!isNil(v)&&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 length(l){return l.length;}
function assoc(k,l){if(isNil(l))
-return mklist();if(k==car(car(l)))
-return car(l);return assoc(k,cdr(l));}
+return emptylist;var n=l.length;for(var i=0;i<n;i++){if(k==car(l[i]))
+return l[i];}
+return emptylist;}
function map(f,l){if(isNil(l))
-return l;return cons(f(car(l)),map(f,cdr(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;}
function filter(f,l){if(isNil(l))
-return l;if(f(car(l)))
-return cons(car(l),filter(f,cdr(l)));return filter(f,cdr(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;}
function reduce(f,i,l){if(isNil(l))
return i;return reduce(f,f(i,car(l)),cdr(l));}
function tokens(path){return filter(function(s){return length(s)!=0;},path.split("/"));}
@@ -50,7 +48,8 @@ config={};function AssertException(){}
AssertException.prototype.toString=function(){return'AssertException';};function assert(exp){if(!exp)
throw new AssertException();}
function writeStrings(l){if(isNil(l))
-return'';return car(l)+writeStrings(cdr(l));}
+return'';var s='';var n=l.length;for(var i=0;i<n;i++){s=s+l[i];}
+return s;}
function writeValue(v){function writePrimitive(p){if(isSymbol(p))
return''+p.substring(1);if(isString(p))
return'"'+p+'"';return''+p;}
@@ -84,18 +83,11 @@ return b;a.length=0;return setappend(a,b);}
var element="'element"
var attribute="'attribute"
var atsign="'@"
-function isElement(v){if(!isList(v)||isNil(v)||car(v)!=element)
-return false;return true;}
-function isAttribute(v){if(!isList(v)||isNil(v)||car(v)!=attribute)
-return false;return true;}
-function attributeName(l){return cadr(l);}
-function attributeValue(l){return caddr(l);}
-function elementName(l){return cadr(l);}
-function elementHasChildren(l){return!isNil(cddr(l));}
-function elementChildren(l){return cddr(l);}
-function elementHasValue(l){r=reverse(l);if(isSymbol(car(r)))
-return false;if(isList(car(r))&&!isNil(car(r))&&isSymbol(car(car(r))))
-return false;return true;}
+function isElement(v){return(!(!isList(v)||isNil(v)||car(v)!=element));}
+function isAttribute(v){return(!(!isList(v)||isNil(v)||car(v)!=attribute));}
+attributeName=cadr;attributeValue=caddr;elementName=cadr;function elementHasChildren(l){return!isNil(cddr(l));}
+elementChildren=cddr;function elementHasValue(l){var r=reverse(l);if(isSymbol(car(r)))
+return false;return(!(isList(car(r))&&!isNil(car(r))&&isSymbol(car(car(r)))))}
function elementValue(l){return car(reverse(l));}
function elementToValueIsList(v){if(!isList(v))
return false;return isNil(v)||!isSymbol(car(v));}
@@ -105,10 +97,7 @@ return mklist(elementName(t),elementValue(t));return cons(elementName(t),mklist(
return cons(elementName(t),elementsToValues(elementChildren(t)));}
if(!isList(t))
return t;return elementsToValues(t);}
-function elementToValueIsSymbol(v){if(!isList(v))
-return false;if(isNil(v))
-return false;if(!isSymbol(car(v)))
-return false;return true;}
+function elementToValueIsSymbol(v){return(!(!isList(v))||isNil(v)||!isSymbol(car(v)));}
function elementToValueGroupValues(v,l){if(isNil(l)||!elementToValueIsSymbol(v)||!elementToValueIsSymbol(car(l)))
return cons(v,l);if(car(car(l))!=car(v))
return cons(v,l);if(!elementToValueIsList(cadr(car(l)))){var g=mklist(car(v),mklist(cdr(v),cdr(car(l))));return elementToValueGroupValues(g,cdr(l));}
@@ -243,12 +232,13 @@ var turi=targetURI();if(isNil(turi))
return turi;return car(tokens(turi));};scdl.properties=function(l){return namedElementChildren("'property",l);};scdl.propertyValue=function(l){if(!elementHasValue(l))
return'';return elementValue(l);};scdl.nameToElementAssoc=function(l){if(isNil(l))
return l;return cons(mklist(scdl.name(car(l)),car(l)),scdl.nameToElementAssoc(cdr(l)));};var ui={};ui.ahref=function(loc,target,html){if(target=='_blank')
-return'<a href="'+loc+'" target="_blank">'+html+'</a>';return'<a href="javascript:void(0)" onclick="window.open(\''+loc+'\', \''+target+'\');">'+html+'</a>';};ui.menu=function(name,href,target){function Menu(n,h,t){this.name=n;this.href=h;this.target=isNil(t)?'_parent':t;this.content=function(){function complete(uri){var q=uri.indexOf('?');if(q!=-1)
+return'<a href="'+loc+'" target="_blank">'+html+'</a>';return'<a href="javascript:void(0)" onclick="ui.navigate(\''+loc+'\', \''+target+'\');">'+html+'</a>';};ui.menu=function(name,href,target){function Menu(n,h,t){this.name=n;this.href=h;this.target=isNil(t)?'_parent':t;this.content=function(){function complete(uri){var h=uri.indexOf('#');if(h!=-1)
+return complete(uri.substr(0,h));var q=uri.indexOf('?');if(q!=-1)
return complete(uri.substr(0,q));if(uri.match('.*\.html$'))
return uri;if(uri.match('.*/$'))
return uri+'index.html';return uri+'/index.html';}
if(complete(this.href)!=complete(window.top.location.pathname))
-return ui.ahref(this.href,this.target,'<span class="amenu">'+this.name+'</span>');return ui.ahref(this.href,this.target,'<span class="smenu">'+this.name+'</span>');};}
+return ui.ahref(this.href,this.target,'<span class="tbaramenu">'+this.name+'</span>');return ui.ahref(this.href,this.target,'<span class="tbarsmenu">'+this.name+'</span>');};}
return new Menu(name,href,target);};ui.menubar=function(left,right){var bar='<table cellpadding="0" cellspacing="0" width="100%" class="tbar"><tr>'+'<td class="dtbar"><table border="0" cellspacing="0" cellpadding="0"><tr>';for(i in left)
bar=bar+'<td class="ltbar">'+left[i].content()+'</td>'
bar=bar+'</tr></table></td>'+'<td class="dtbar"><table border="0" cellpadding="0" cellspacing="0" align="right"><tr>';for(i in right)
@@ -267,18 +257,30 @@ items+='</table>';this.suggestDiv.innerHTML=items;if(items.length!=0){var node=i
break;}
this.suggestDiv.style.left=left;this.suggestDiv.style.top=top+input.offsetHeight;this.suggestDiv.style.visibility='visible';}else
this.suggestDiv.style.visibility='hidden';}
-input.onkeydown=function(event){this.showSuggestDiv();};input.onkeyup=function(event){this.showSuggestDiv();};input.onmousedown=function(event){this.showSuggestDiv();};input.onblur=function(event){setTimeout(function(){input.hideSuggestDiv();},50);};};ui.content=function(win){if(!isNil(win.document))
-return win.document;if(!isNil(win.contentDocument))
-return win.contentDocument;return null;};ui.elementByID=function(node,id){for(var i in node.childNodes){var child=node.childNodes[i];if(child.id==id)
+input.onkeydown=function(event){this.showSuggestDiv();};input.onkeyup=function(event){this.showSuggestDiv();};input.onmousedown=function(event){this.showSuggestDiv();};input.onblur=function(event){setTimeout(function(){input.hideSuggestDiv();},50);};};ui.elementByID=function(node,id){for(var i in node.childNodes){var child=node.childNodes[i];if(child.id==id)
return child;var gchild=ui.elementByID(child,id);if(gchild!=null)
return gchild;}
return null;};function $(id){if(id==document){if(!isNil(document.widget))
return document.widget;return document;}
return ui.elementByID($(document),id);};ui.queryParams=function(){var qp=new Array();var qs=window.location.search.substring(1).split('&');for(var i=0;i<qs.length;i++){var e=qs[i].indexOf('=');if(e>0)
qp[qs[i].substring(0,e)]=unescape(qs[i].substring(e+1));}
-return qp;};ui.isMobile=function(){var ua=navigator.userAgent;if(ua.match(/iPhone/i)||ua.match(/iPad/i)||ua.match(/Android/i)||ua.match(/Blackberry/i)||ua.match(/WebOs/i))
-return true;return false;};ui.onload=function(){document.body.style.visibility='visible';document.body.onorientationchange=function(){window.open(window.location,'_self');return true;};return true;};ui.numpos=function(p){if(p=='')
-return 0;return Number(p.substr(0,p.length-2));};ui.pixpos=function(p){return p+'px';};ui.datatable=function(l){function indent(i){if(i==0)
+return qp;};ui.fragmentParams=function(){var qp=new Array();var qs=window.location.hash.substring(1).split('&');for(var i=0;i<qs.length;i++){var e=qs[i].indexOf('=');if(e>0)
+qp[qs[i].substring(0,e)]=unescape(qs[i].substring(e+1));}
+return qp;};ui.mobiledetected=false;ui.mobile=false;ui.isMobile=function(){if(ui.mobiledetected)
+return ui.mobile;var ua=navigator.userAgent;if(ua.match(/iPhone/i)||ua.match(/iPad/i)||ua.match(/Android/i)||ua.match(/Blackberry/i)||ua.match(/WebOs/i))
+ui.mobile=true;ui.mobiledetected=true;return ui.mobile;};ui.pagetransitions=false;ui.initbody=function(){if(ui.isMobile()){if(ui.pagetransitions){var bdiv=$('bodydiv');if(!isNil(bdiv)){bdiv.className='bodydivloading';}}
+document.body.onorientationchange=ui.onorientationchange;}
+return true;}
+ui.onorientationchange=function(){window.open(window.location,'_self');return true;}
+ui.onload=function(){var path=document.location.pathname;if(path.indexOf('/login/')!=0&&path.indexOf('/logout/')!=0)
+localStorage.setItem('ui.lastvisited',''+document.location);document.body.style.visibility='visible';if(ui.pagetransitions&&ui.isMobile()){setTimeout(function(){var bdiv=$('bodydiv');if(!isNil(bdiv)){function transitionend(e){bdiv.removeEventListener('webkitTransitionEnd',transitionend,false);bdiv.removeEventListener('transitionend',transitionend,false);bdiv.className='bodydiv';};bdiv.addEventListener('webkitTransitionEnd',transitionend,false);bdiv.addEventListener('transitionend',transitionend,false);bdiv.className='bodydivloaded';}},0);}
+return true;};ui.navigate=function(url,win){function opendoc(url,win){if(win=='_reload'){window.location=url;return window.location.reload();}
+return window.open(url,win);}
+if(ui.pagetransitions&&ui.isMobile()&&win!='_blank'){var bdiv=$('bodydiv');if(!isNil(bdiv)){function transitionend(e){bdiv.removeEventListener('webkitTransitionEnd',transitionend,false);bdiv.removeEventListener('transitionend',transitionend,false);return opendoc(url,win);};bdiv.addEventListener('webkitTransitionEnd',transitionend,false);bdiv.addEventListener('transitionend',transitionend,false);bdiv.className='bodydivunloaded';return true;}}
+return opendoc(url,win);}
+ui.onbeforeunload=function(){if(ui.pagetransitions&&ui.isMobile()){var bdiv=$('bodydiv');if(!isNil(bdiv))
+bdiv.className='bodydivunloaded';}};ui.lastvisited=function(){return localStorage.getItem('ui.lastvisited');}
+ui.numpos=function(p){return p==''?0:Number(p.substr(0,p.length-2));};ui.pixpos=function(p){return p+'px';};ui.datatable=function(l){function indent(i){if(i==0)
return'';return'&nbsp;&nbsp;'+indent(i-1);}
function rows(l,i){if(isNil(l))
return'';var e=car(l);if(!isList(e))
@@ -310,30 +312,31 @@ return"{"+v.join(", ")+"}";};function HTTPBindingClient(name,uri){this.name=name
HTTPBindingClient.jsonrpcID=1;HTTPBindingClient.prototype.createApplyMethod=function(){var fn=function(){var methodName=arguments[0];var args=[];for(var i=1;i<arguments.length;i++)
args.push(arguments[i]);var cb=null;if(typeof args[args.length-1]=="function")
cb=args.pop();var req=HTTPBindingClient.makeJSONRequest(methodName,args,cb);return fn.client.jsonApply(req);};fn.client=this;return fn;};HTTPBindingClient.makeJSONRequest=function(methodName,args,cb){var req={};req.id=HTTPBindingClient.jsonrpcID++;if(cb)
-req.cb=cb;var obj={};obj.id=req.id;obj.method=methodName;obj.params=args;req.data=JSONClient.toJSON(obj);return req;};HTTPBindingClient.jsonResult=function(http){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=")
+req.cb=cb;var obj={};obj.id=req.id;obj.method=methodName;obj.params=args;req.data=JSONClient.toJSON(obj);return req;};HTTPBindingClient.jsonResult=function(http){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);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;};HTTPBindingClient.prototype.jsonApply=function(req){var http=HTTPBindingClient.getHTTPRequest();var hascb=req.cb?true:false;http.open("POST",this.uri,hascb);http.setRequestHeader("Content-type","application/json-rpc");if(hascb){http.onreadystatechange=function(){if(http.readyState==4){if(http.status==200){var res=null;try{res=HTTPBindingClient.jsonResult(http);}catch(e){req.cb(null,e);}
-req.cb(res);}else
-req.cb(null,HTTPBindingClient.Exception(http.status,http.statusText));}};http.send(req.data);return req.id;}
+throw new HTTPBindingClient.Exception(obj.error.code,obj.error.msg);var res=obj.result;return res;};HTTPBindingClient.prototype.jsonApply=function(req){var http=HTTPBindingClient.getHTTPRequest();var hascb=req.cb?true:false;http.open("POST",this.uri,hascb);http.setRequestHeader("Content-Type","application/json-rpc");if(hascb){http.onreadystatechange=function(){if(http.readyState==4){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){}}};http.send(req.data);return req.id;}
http.send(req.data);if(http.status==200)
-return HTTPBindingClient.jsonResult(http);throw new HTTPBindingClient.Exception(http.status,http.statusText);};HTTPBindingClient.prototype.get=function(id,cb){var http=HTTPBindingClient.getHTTPRequest();var hascb=cb?true:false;http.open("GET",this.uri+'/'+id,hascb);if(hascb){http.onreadystatechange=function(){if(http.readyState==4){if(http.status==200)
-cb(http.responseText);else
-cb(null,new HTTPBindingClient.Exception(http.status,http.statusText));}};http.send(null);return true;}
-http.send(null);if(http.status==200)
-return http.responseText;throw new HTTPBindingClient.Exception(http.status,http.statusText);};HTTPBindingClient.prototype.post=function(entry,cb){var http=HTTPBindingClient.getHTTPRequest();var hascb=cb?true:false;http.open("POST",this.uri,hascb);http.setRequestHeader("Content-Type","application/atom+xml");if(hascb){http.onreadystatechange=function(){if(http.readyState==4){if(http.status==201)
-cb(http.responseText);else
-cb(null,new HTTPBindingClient.Exception(http.status,http.statusText));}};http.send(entry);return true;}
+return HTTPBindingClient.jsonResult(http);throw new HTTPBindingClient.Exception(http.status,http.statusText);};HTTPBindingClient.prototype.get=function(id,cb){var u=this.uri+'/'+id;var hascb=cb?true:false;var item=localStorage.getItem(u);if(item!=null&&item!=''){if(!hascb)
+return item;try{cb(item);}catch(cbe){}}
+var http=HTTPBindingClient.getHTTPRequest();http.open("GET",u,hascb);if(hascb){http.onreadystatechange=function(){if(http.readyState==4){if(http.status==200){if(http.getResponseHeader("X-Login")!=null){try{cb(null,new HTTPBindingClient.Exception(403,'X-Login'));}catch(cbe){}}else if(http.responseText==''||http.getResponseHeader("Content-Type")==null){try{cb(null,new HTTPBindingClient.Exception(403,'No-Content'));}catch(cbe){}}else{if(item==null||http.responseText!=item){if(http.responseText!=null){localStorage.setItem(u,http.responseText);}
+try{cb(http.responseText);}catch(cbe){}}}}
+else{if(item==null){try{cb(null,new HTTPBindingClient.Exception(http.status,http.statusText));}catch(cbe){}}}}};http.send(null);return true;}
+http.send(null);if(http.status==200){if(http.getResponseHeader("X-Login")!=null){throw new HTTPBindingClient.Exception(403,'X-Login');}else if(http.responseText==''||http.getResponseHeader("Content-Type")==null){throw new HTTPBindingClient.Exception(403,'No-Content');}
+return http.responseText;}
+throw new HTTPBindingClient.Exception(http.status,http.statusText);};HTTPBindingClient.prototype.getnocache=function(id,cb){var u=this.uri+'/'+id;var hascb=cb?true:false;var http=HTTPBindingClient.getHTTPRequest();http.open("GET",u,hascb);if(hascb){http.onreadystatechange=function(){if(http.readyState==4){if(http.status==200){if(http.getResponseHeader("X-Login")!=null){try{return cb(null,new HTTPBindingClient.Exception(403,'X-Login'));}catch(cbe){}}else if(http.responseText==''||http.getResponseHeader("Content-Type")==null){try{return cb(null,new HTTPBindingClient.Exception(403,'No-Content'));}catch(cbe){}}else{try{cb(http.responseText);}catch(cbe){}}}else{try{cb(null,new HTTPBindingClient.Exception(http.status,http.statusText));}catch(cbe){}}}};http.send(null);return true;}
+http.send(null);if(http.status==200){if(http.getResponseHeader("X-Login")!=null){throw new HTTPBindingClient.Exception(403,'X-Login');}else if(http.responseText==''||http.getResponseHeader("Content-Type")==null){throw new HTTPBindingClient.Exception(403,'No-Content');}
+return http.responseText;}
+throw new HTTPBindingClient.Exception(http.status,http.statusText);};HTTPBindingClient.prototype.post=function(entry,cb){var http=HTTPBindingClient.getHTTPRequest();var hascb=cb?true:false;http.open("POST",this.uri,hascb);http.setRequestHeader("Content-Type","application/atom+xml");if(hascb){http.onreadystatechange=function(){if(http.readyState==4){if(http.status==201){try{cb(http.responseText);}catch(cbe){}}
+else{try{cb(null,new HTTPBindingClient.Exception(http.status,http.statusText));}catch(cbe){}}}};http.send(entry);return true;}
http.send(entry);if(http.status==201)
-return http.responseText;throw new HTTPBindingClient.Exception(http.status,http.statusText);};HTTPBindingClient.prototype.put=function(id,entry,cb){var http=HTTPBindingClient.getHTTPRequest();var hascb=cb?true:false;http.open("PUT",this.uri+'/'+id,hascb);http.setRequestHeader("Content-Type","application/atom+xml");if(hascb){http.onreadystatechange=function(){if(http.readyState==4){if(http.status==200)
-cb();else
-cb(new HTTPBindingClient.Exception(http.status,http.statusText));}};http.send(entry);return true;}
+return http.responseText;throw new HTTPBindingClient.Exception(http.status,http.statusText);};HTTPBindingClient.prototype.put=function(id,entry,cb){var u=this.uri+'/'+id;localStorage.setItem(u,entry);var http=HTTPBindingClient.getHTTPRequest();var hascb=cb?true:false;http.open("PUT",u,hascb);http.setRequestHeader("Content-Type","application/atom+xml");if(hascb){http.onreadystatechange=function(){if(http.readyState==4){if(http.status==200){try{cb();}catch(cbe){}}else{try{cb(new HTTPBindingClient.Exception(http.status,http.statusText));}catch(cbe){}}}};http.send(entry);return true;}
http.send(entry);if(http.status==200)
-return true;throw new HTTPBindingClient.Exception(http.status,http.statusText);};HTTPBindingClient.prototype.del=function(id,cb){var http=HTTPBindingClient.getHTTPRequest();var hascb=cb?true:false;http.open("DELETE",this.uri+'/'+id,hascb);if(cb){http.onreadystatechange=function(){if(http.readyState==4){if(http.status==200)
-cb();else
-cb(new HTTPBindingClient.Exception(http.status,http.statusText));}};http.send(null);return true;}
+return true;throw new HTTPBindingClient.Exception(http.status,http.statusText);};HTTPBindingClient.prototype.del=function(id,cb){var u=this.uri+'/'+id;localStorage.removeItem(u);var http=HTTPBindingClient.getHTTPRequest();var hascb=cb?true:false;http.open("DELETE",u,hascb);if(cb){http.onreadystatechange=function(){if(http.readyState==4){if(http.status==200){try{cb();}catch(cbe){}}
+else{try{cb(new HTTPBindingClient.Exception(http.status,http.statusText));}catch(cbe){}}}};http.send(null);return true;}
http.send(null);if(http.status==200)
return true;throw new HTTPBindingClient.Exception(http.status,http.statusText);};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;};HTTPBindingClient.msxmlNames=["MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"];HTTPBindingClient.getHTTPRequest=function(){if(HTTPBindingClient.httpFactory)
return HTTPBindingClient.httpFactory();try{HTTPBindingClient.httpFactory=function(){return new XMLHttpRequest();};return HTTPBindingClient.httpFactory();}catch(e){}
diff --git a/sca-cpp/trunk/modules/js/htdocs/component.js b/sca-cpp/trunk/modules/js/htdocs/component.js
index 3712ee59cb..742e7be930 100644
--- a/sca-cpp/trunk/modules/js/htdocs/component.js
+++ b/sca-cpp/trunk/modules/js/htdocs/component.js
@@ -161,7 +161,7 @@ HTTPBindingClient.jsonResult = function(http) {
// Get the charset
function httpCharset(http) {
try {
- var contentType = http.getResponseHeader("Content-type");
+ 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=")
@@ -190,7 +190,7 @@ HTTPBindingClient.prototype.jsonApply = function(req) {
var http = HTTPBindingClient.getHTTPRequest();
var hascb = req.cb? true : false;
http.open("POST", this.uri, hascb);
- http.setRequestHeader("Content-type", "application/json-rpc");
+ http.setRequestHeader("Content-Type", "application/json-rpc");
// Construct call back if we have one
if(hascb) {
@@ -201,12 +201,18 @@ HTTPBindingClient.prototype.jsonApply = function(req) {
var res = null;
try {
res = HTTPBindingClient.jsonResult(http);
+ try {
+ req.cb(res);
+ } catch(cbe) {}
} catch(e) {
- req.cb(null, e);
+ try {
+ req.cb(null, e);
+ } catch(cbe) {}
}
- req.cb(res);
} else
- req.cb(null, HTTPBindingClient.Exception(http.status, http.statusText));
+ try {
+ req.cb(null, HTTPBindingClient.Exception(http.status, http.statusText));
+ } catch(cbe) {}
}
};
@@ -222,24 +228,137 @@ HTTPBindingClient.prototype.jsonApply = function(req) {
throw new HTTPBindingClient.Exception(http.status, http.statusText);
};
+
/**
* REST ATOMPub GET method.
*/
HTTPBindingClient.prototype.get = function(id, cb) {
+ var u = this.uri + '/' + id;
+ var hascb = cb? true : false;
+
+ // Get from local storage first
+ var item = localStorage.getItem(u);
+ //log('localStorage.getItem', u, item);
+ if (item != null && item != '') {
+ if (!hascb)
+ return item;
+
+ // Pass local result to callback
+ try {
+ cb(item);
+ } catch (cbe) {}
+ }
+
// Connect to the service
var http = HTTPBindingClient.getHTTPRequest();
+ http.open("GET", u, hascb);
+
+ // Construct call back if we have one
+ if (hascb) {
+ http.onreadystatechange = function() {
+ //log('readystate', http.readyState, 'status', http.status, 'headers', http.getAllResponseHeaders());
+ if (http.readyState == 4) {
+ // Pass result if different from local result
+ if (http.status == 200) {
+
+ if (http.getResponseHeader("X-Login") != null) {
+ // Detect redirect to a login page
+ try {
+ cb(null, new HTTPBindingClient.Exception(403, 'X-Login'));
+ } catch(cbe) {}
+
+ } else if (http.responseText == '' || http.getResponseHeader("Content-Type") == null) {
+ // Report empty response
+ try {
+ cb(null, new HTTPBindingClient.Exception(403, 'No-Content'));
+ } catch(cbe) {}
+
+ } else {
+ if (item == null || http.responseText != item) {
+ // Store retrieved entry in local storage
+ if (http.responseText != null) {
+ //log('localStorage.setItem', u, http.responseText);
+ localStorage.setItem(u, http.responseText);
+ }
+ try {
+ cb(http.responseText);
+ } catch(cbe) {}
+ }
+ }
+ }
+ else {
+ // Pass exception if we didn't have a local result
+ if (item == null) {
+ try {
+ cb(null, new HTTPBindingClient.Exception(http.status, http.statusText));
+ } catch(cbe) {}
+ }
+ }
+ }
+ };
+
+ // Send the request
+ http.send(null);
+ return true;
+ }
+
+ // Send the request and return the result or exception
+ http.send(null);
+ if (http.status == 200) {
+ if (http.getResponseHeader("X-Login") != null) {
+
+ // Detect redirect to a login page
+ throw new HTTPBindingClient.Exception(403, 'X-Login');
+
+ } else if (http.responseText == '' || http.getResponseHeader("Content-Type") == null) {
+
+ // Report empty response
+ throw new HTTPBindingClient.Exception(403, 'No-Content');
+ }
+ return http.responseText;
+ }
+ throw new HTTPBindingClient.Exception(http.status, http.statusText);
+};
+
+/**
+ * REST ATOMPub GET method, does not use the local cache.
+ */
+HTTPBindingClient.prototype.getnocache = function(id, cb) {
+ var u = this.uri + '/' + id;
var hascb = cb? true : false;
- http.open("GET", this.uri + '/' + id, hascb);
+
+ // Connect to the service
+ var http = HTTPBindingClient.getHTTPRequest();
+ http.open("GET", u, hascb);
// Construct call back if we have one
if (hascb) {
http.onreadystatechange = function() {
if (http.readyState == 4) {
- // Pass the result or exception
- if (http.status == 200)
- cb(http.responseText);
- else
- cb(null, new HTTPBindingClient.Exception(http.status, http.statusText));
+ if (http.status == 200) {
+
+ if (http.getResponseHeader("X-Login") != null) {
+ // Detect redirect to a login page
+ try {
+ return cb(null, new HTTPBindingClient.Exception(403, 'X-Login'));
+ } catch(cbe) {}
+
+ } else if (http.responseText == '' || http.getResponseHeader("Content-Type") == null) {
+ // Report empty response
+ try {
+ return cb(null, new HTTPBindingClient.Exception(403, 'No-Content'));
+ } catch(cbe) {}
+
+ } else {
+ try {
+ cb(http.responseText);
+ } catch(cbe) {}
+ }
+ } else {
+ try {
+ cb(null, new HTTPBindingClient.Exception(http.status, http.statusText));
+ } catch(cbe) {}
+ }
}
};
@@ -250,8 +369,19 @@ HTTPBindingClient.prototype.get = function(id, cb) {
// Send the request and return the result or exception
http.send(null);
- if (http.status == 200)
+ if (http.status == 200) {
+ if (http.getResponseHeader("X-Login") != null) {
+
+ // Detect redirect to a login page
+ throw new HTTPBindingClient.Exception(403, 'X-Login');
+
+ } else if (http.responseText == '' || http.getResponseHeader("Content-Type") == null) {
+
+ // Report empty response
+ throw new HTTPBindingClient.Exception(403, 'No-Content');
+ }
return http.responseText;
+ }
throw new HTTPBindingClient.Exception(http.status, http.statusText);
};
@@ -259,6 +389,7 @@ HTTPBindingClient.prototype.get = function(id, cb) {
* REST ATOMPub POST method.
*/
HTTPBindingClient.prototype.post = function (entry, cb) {
+
// Connect to the service
var http = HTTPBindingClient.getHTTPRequest();
var hascb = cb? true : false;
@@ -270,10 +401,16 @@ HTTPBindingClient.prototype.post = function (entry, cb) {
http.onreadystatechange = function() {
// Pass the result or exception
if (http.readyState == 4) {
- if (http.status == 201)
- cb(http.responseText);
- else
- cb(null, new HTTPBindingClient.Exception(http.status, http.statusText));
+ if (http.status == 201) {
+ try {
+ cb(http.responseText);
+ } catch(cbe) {}
+ }
+ else {
+ try {
+ cb(null, new HTTPBindingClient.Exception(http.status, http.statusText));
+ } catch(cbe) {}
+ }
}
};
// Send the request
@@ -292,10 +429,16 @@ HTTPBindingClient.prototype.post = function (entry, cb) {
* REST ATOMPub PUT method.
*/
HTTPBindingClient.prototype.put = function (id, entry, cb) {
+ var u = this.uri + '/' + id;
+
+ // Update local storage
+ localStorage.setItem(u, entry);
+ //log('localStorage.setItem', u, entry);
+
// Connect to the service
var http = HTTPBindingClient.getHTTPRequest();
var hascb = cb? true : false;
- http.open("PUT", this.uri + '/' + id, hascb);
+ http.open("PUT", u, hascb);
http.setRequestHeader("Content-Type", "application/atom+xml");
// Construct call back if we have one
@@ -303,10 +446,15 @@ HTTPBindingClient.prototype.put = function (id, entry, cb) {
http.onreadystatechange = function() {
if (http.readyState == 4) {
// Pass any exception
- if (http.status == 200)
- cb();
- else
- cb(new HTTPBindingClient.Exception(http.status, http.statusText));
+ if (http.status == 200) {
+ try {
+ cb();
+ } catch(cbe) {}
+ } else {
+ try {
+ cb(new HTTPBindingClient.Exception(http.status, http.statusText));
+ } catch(cbe) {}
+ }
}
};
// Send the request
@@ -325,20 +473,32 @@ HTTPBindingClient.prototype.put = function (id, entry, cb) {
* REST ATOMPub DELETE method.
*/
HTTPBindingClient.prototype.del = function (id, cb) {
+ var u = this.uri + '/' + id;
+
+ // Update local storage
+ localStorage.removeItem(u);
+ //log('localStorage.removeItem', u);
+
// Connect to the service
var http = HTTPBindingClient.getHTTPRequest();
var hascb = cb? true : false;
- http.open("DELETE", this.uri + '/' + id, hascb);
+ http.open("DELETE", u, hascb);
// Construct call back if we have one
if (cb) {
http.onreadystatechange = function() {
if (http.readyState == 4) {
// Pass any exception
- if (http.status == 200)
- cb();
- else
- cb(new HTTPBindingClient.Exception(http.status, http.statusText));
+ if (http.status == 200) {
+ try {
+ cb();
+ } catch(cbe) {}
+ }
+ else {
+ try {
+ cb(new HTTPBindingClient.Exception(http.status, http.statusText));
+ } catch(cbe) {}
+ }
}
};
// Send the request
diff --git a/sca-cpp/trunk/modules/js/htdocs/elemutil.js b/sca-cpp/trunk/modules/js/htdocs/elemutil.js
index 1c006e1e7c..37d641f7b3 100644
--- a/sca-cpp/trunk/modules/js/htdocs/elemutil.js
+++ b/sca-cpp/trunk/modules/js/htdocs/elemutil.js
@@ -29,40 +29,30 @@ var atsign = "'@"
* Return true if a value is an element.
*/
function isElement(v) {
- if (!isList(v) || isNil(v) || car(v) != element)
- return false;
- return true;
+ return (!(!isList(v) || isNil(v) || car(v) != element));
}
/**
* Return true if a value is an attribute.
*/
function isAttribute(v) {
- if (!isList(v) || isNil(v) || car(v) != attribute)
- return false;
- return true;
+ return (!(!isList(v) || isNil(v) || car(v) != attribute));
}
/**
* Return the name of an attribute.
*/
-function attributeName(l) {
- return cadr(l);
-}
+attributeName = cadr;
/**
* Return the value of an attribute.
*/
-function attributeValue(l) {
- return caddr(l);
-}
+attributeValue = caddr;
/**
* Return the name of an element.
*/
-function elementName(l) {
- return cadr(l);
-}
+elementName = cadr;
/**
* Return true if an element has children.
@@ -74,21 +64,16 @@ function elementHasChildren(l) {
/**
* Return the children of an element.
*/
-function elementChildren(l) {
- return cddr(l);
-}
-
+elementChildren = cddr;
/**
* Return true if an element has a value.
*/
function elementHasValue(l) {
- r = reverse(l);
+ var r = reverse(l);
if (isSymbol(car(r)))
return false;
- if (isList(car(r)) && !isNil(car(r)) && isSymbol(car(car(r))))
- return false;
- return true;
+ return (!(isList(car(r)) && !isNil(car(r)) && isSymbol(car(car(r)))))
}
/**
@@ -127,13 +112,7 @@ function elementToValue(t) {
* Convert a list of elements to a list of values.
*/
function elementToValueIsSymbol(v) {
- if (!isList(v))
- return false;
- if (isNil(v))
- return false;
- if (!isSymbol(car(v)))
- return false;
- return true;
+ return (!(!isList(v)) || isNil(v) || !isSymbol(car(v)));
}
function elementToValueGroupValues(v, l) {
diff --git a/sca-cpp/trunk/modules/js/htdocs/ui-min.css b/sca-cpp/trunk/modules/js/htdocs/ui-min.css
index c4cdc288a1..c8798583c6 100644
--- a/sca-cpp/trunk/modules/js/htdocs/ui-min.css
+++ b/sca-cpp/trunk/modules/js/htdocs/ui-min.css
@@ -1,13 +1,17 @@
-body{margin:2px;font-family:"Helvetica Neue", Helvetica;font-style:normal;font-variant:normal;font-size:13px;-webkit-text-size-adjust:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-user-select:none;}
+body{margin-top:0px;margin-bottom:2px;margin-left:2px;margin-right:2px;font-family:"Helvetica Neue", Helvetica;font-style:normal;font-variant:normal;font-size:13px;-webkit-text-size-adjust:none;-webkit-touch-callout:none;-webkit-user-select:none;}
.delayed{visibility:hidden;}
-.devicewidth{position:absolute;top:0px;left:0px;right:0px;height:5000px;overflow:hidden;}
+.devicewidth{position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:hidden;}
+.bodydiv{position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:hidden;}
+.bodydivloading{position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:hidden;-webkit-transform:translate(100%, 0px);-webkit-backface-visibility:hidden;-moz-transform:translate(100%, 0px);-ms-transform:translate(100%, 0px);transform:translate(100%, 0px);}
+.bodydivloaded{-webkit-transition:-webkit-transform 0.4s linear;-moz-transition:-moz-transform 0.4s linear;-ms-transition:-ms-transform 0.4s linear;transition:transform 0.4s linear;position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:hidden;-webkit-transform:translate3d(0px, 0px, 0px);-webkit-backface-visibility:hidden;-moz-transform:translate(0px, 0px);-ms-transform:translate(0px, 0px);transform:translate(0px, 0px);}
+.bodydivunloaded{-webkit-transition:-webkit-transform 0.4s linear;-moz-transition:-moz-transform 0.4s linear;-ms-transition:-ms-transform 0.4s linear;transition:transform 0.4s linear;position:absolute;top:0px;left:0px;width:100%;height:5000px;overflow:hidden;-webkit-transform:translate3d(-100%, 0px, 0px);-webkit-backface-visibility:hidden;-moz-transform:translate(-100%, 0px);-ms-transform:translate(-100%, 0px);transform:translate(-100%, 0px);}
table{border:0px;border-collapse:collapse;border-color:#a2bae7;border-style:solid;font-family:"Helvetica Neue", Helvetica;font-style:normal;font-variant:normal;font-size:13px;overflow:visible;}
.trb{border-bottom:1px;border-bottom-style:solid;border-color:#dcdcdc;}
-th{font-weight:bold;background-color:#e5ecf9;color:#000000;height:18px;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:#a2bae7;border-bottom-color:#d1d3d4;border-left-color:#a2bae7;border-right-color:#a2bae7;overflow:hidden;}
-.section{font-weight:bold;background-color:#e5ecf9;color:#000000;height:24px;padding-top:1px;padding-bottom:0px;padding-left:2px;padding-right:2px;border-top:1px;border-bottom:1px;border-left:0px;border-right:0px;border-style:solid;border-top-color:#a2bae7;border-bottom-color:#d1d3d4;border-left-color:#a2bae7;border-right-color:#a2bae7;overflow:hidden;}
-.hsection{width:100%;height:50px;border-top:0px;border-bottom:1px;border-left:0px;border-right:0px;border-style:solid;border-bottom-color:#000000;background-color:#ffffff;padding:0px;margin-bottom:4px;margin-left:auto;margin-right:auto;text-align:center;}
-.fsection{width:100%;height:50px;border-top:0px;border-bottom:0px;border-left:0px;border-right:0px;border-style:solid;border-top-color:#a2bae7;padding:0px;margin-top:4px;margin-left:auto;margin-right:auto;text-align:center;}
-.text{padding-top:3px;padding-bottom:4px;vertical-align:middle;}
+th{font-weight:bold;background-color:#d4e6fc;color:#000000;height:18px;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:#a2bae7;border-bottom-color:#d1d3d4;border-left-color:#a2bae7;border-right-color:#a2bae7;overflow:hidden;}
+.section{font-weight:bold;background-color:#d4e6fc;color:#000000;height:24px;padding-top:1px;padding-bottom:0px;padding-left:2px;padding-right:2px;border-top:1px;border-bottom:1px;border-left:0px;border-right:0px;border-style:solid;border-top-color:#a2bae7;border-bottom-color:#d1d3d4;border-left-color:#a2bae7;border-right-color:#a2bae7;overflow:hidden;}
+.hsection{width:100%;height:50px;border-top:0px;border-bottom:0px;border-left:0px;border-right:0px;border-style:solid;border-bottom-color:#000000;background-color:#ffffff;padding:0px;margin-bottom:0px;margin-left:auto;margin-right:auto;text-align:center;}
+.fsection{width:100%;height:50px;border-top:0px;border-bottom:0px;border-left:0px;border-right:0px;border-style:solid;border-top-color:#a2bae7;padding:0px;margin-top:0px;margin-left:auto;margin-right:auto;text-align:center;}
+.text{padding-top:3px;padding-bottom:4px;vertical-align:middle;white-space:nowrap;}
.thl{border-left:0px;}
.thr{border-right:0px;}
.ths{padding:0px;}
@@ -26,28 +30,31 @@ iframe{border:0px;margin:0px;padding:0px;}
input{vertical-align:middle;font-family:"Helvetica Neue", Helvetica;font-style:normal;font-variant:normal;font-size:13px;-webkit-text-size-adjust:100%;}
textarea{font-family:"Helvetica Neue", Helvetica;font-style:normal;font-variant:normal;font-size:13px;overflow:auto;resize:none;}
.editable{background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-size:inherit;font-weight:inherit;padding:0px;margin:0px;overflow:auto;resize:none;outline:none;-webkit-appearance:none;-moz-outline-style:none;-webkit-text-size-adjust:100%;border:0px;}
-a:link{color:#598edd;text-decoration:none;}
-a:visited{color:#598edd;text-decoration:none;}
-.amenu{color:#598edd;text-decoration:none;}
-.smenu{font-weight:bold;color:#000000;text-decoration:none;}
-h1{font-size:150%;font-weight:bold;vertical-align:middle;margin-top:5px;margin-bottom:5px;margin-left:2px;margin-right:2px;}
-h2{font-size:120%;font-weight:bold;vertical-align:middle;margin-top:5px;margin-bottom:5px;margin-left:2px;margin-right:2px;}
-.hd1{font-size:150%;font-weight:bold;}
-.hd2{font-size:120%;font-weight:bold;}
+a:link{color:#598edd;text-decoration:none;white-space:nowrap;}
+a:visited{color:#598edd;text-decoration:none;white-space:nowrap;}
+.amenu{color:#598edd;text-decoration:none;white-space:nowrap;}
+.smenu{font-weight:bold;color:#000000;text-decoration:none;white-space:nowrap;}
+h1{font-size:150%;font-weight:bold;vertical-align:middle;margin-top:5px;margin-bottom:5px;margin-left:2px;margin-right:2px;white-space:nowrap;}
+h2{font-size:120%;font-weight:bold;vertical-align:middle;margin-top:5px;margin-bottom:5px;margin-left:2px;margin-right:2px;white-space:nowrap;}
+.hd1{font-size:150%;font-weight:bold;white-space:nowrap;}
+.hd2{font-size:120%;font-weight:bold;white-space:nowrap;}
img{border:0px;}
.imgbutton{width:142px;height:64px;margin-left:20px;margin-right:20px;padding:0px;border:1px;cursor:pointer;}
.toolbutton{font-weight:bold;font-size:16px;display:inline-block;width:24px;height:20px;padding:0px;vertical-align:middle;text-align:center;margin-left:0px;margin-right:0px;padding-left:0px;padding-right:0px;padding-top:0px;padding-bottom:0px;}
-.greenbutton{-webkit-border-radius:4px;border-radius:4px;background:#96d333;background:-moz-linear-gradient(top, #f8f8f8 0%, #96d333 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#96d333));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#96d333',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#96d333 100%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;cursor:pointer;}
-.tgreenbutton{-webkit-border-radius:4px;border-radius:4px;background:#96d333;background:-moz-linear-gradient(top, #f8f8f8 0%, #96d333 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#96d333));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#96d333',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#96d333 100%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;cursor:pointer;}
-.bluebutton{-webkit-border-radius:4px;border-radius:4px;background:#598edd;background:-moz-linear-gradient(top, #f8f8f8 0%, #598edd 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#598edd));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#598edd',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#598edd 100%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;cursor:pointer;}
-.redbutton{-webkit-border-radius:4px;border-radius:4px;background:#d03f41;background:-moz-linear-gradient(top, #f8f8f8 0%, #d03f41 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#d03f41));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#d03f41',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#d03f41 100%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;cursor:pointer;}
-.orangebutton{-webkit-border-radius:4px;border-radius:4px;background:#ffbb00;background:-moz-linear-gradient(top, #f8f8f8 0%, #ffbb00 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#ffbb00));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#ffbb00',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#ffbb00 100%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;cursor:pointer;}
-.graybutton{-webkit-border-radius:4px;border-radius:4px;background:#dcdcdc;background:-moz-linear-gradient(top, #f8f8f8 0%, #dcdcdc 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dcdcdc));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#dcdcdc',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#dcdcdc 100%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;margin:2px;cursor:pointer;}
-.tbar{margin:0px;width:100%;padding-top:0px;padding-left:0px;padding-right:0px;padding-bottom:3px;border-bottom:1px solid #a2bae7;border-collapse:separate;}
-.ltbar{padding-left:2px;padding-top:2px;padding-right:6px;white-space:nowrap;vertical-align:middle;}
-.dtbar{padding-left:0px;padding-right:0px;padding-top:2px;white-space:nowrap;vertical-align:middle;text-align:right;}
-.rtbar{padding-left:6px;padding-right:2px;padding-top:2px;white-space:nowrap;vertical-align:middle;text-align:right;}
-.suggest{background-color:#e5ecf9;color:#598edd;border-top:1px;border-bottom:1px;border-left:1px;border-right:1px;border-style:solid;border-top-color:#a2bae7;border-bottom-color:#d1d3d4;border-left-color:#d1d3d4;border-right-color:#d1d3d4;position:absolute;overflow:auto;overflow-x:hidden;padding:0px;margin:0px;cursor:default;}
+.greenbutton{-webkit-border-radius:4px;border-radius:4px;background:#96d333;background:-moz-linear-gradient(top, #f8f8f8 0%, #96d333 80%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#96d333));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#96d333',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#96d333 80%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;cursor:pointer;}
+.tgreenbutton{-webkit-border-radius:4px;border-radius:4px;background:#96d333;background:-moz-linear-gradient(top, #f8f8f8 0%, #96d333 80%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#96d333));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#96d333',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#96d333 80%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;cursor:pointer;}
+.bluebutton{-webkit-border-radius:4px;border-radius:4px;background:#598edd;background:-moz-linear-gradient(top, #f8f8f8 0%, #598edd 80%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#598edd));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#598edd',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#598edd 80%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;cursor:pointer;}
+.redbutton{-webkit-border-radius:4px;border-radius:4px;background:#d03f41;background:-moz-linear-gradient(top, #f8f8f8 0%, #d03f41 80%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#d03f41));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#d03f41',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#d03f41 80%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;cursor:pointer;}
+.orangebutton{-webkit-border-radius:4px;border-radius:4px;background:#ffbb00;background:-moz-linear-gradient(top, #f8f8f8 0%, #ffbb00 80%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#ffbb00));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#ffbb00',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#ffbb00 80%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;cursor:pointer;}
+.graybutton{-webkit-border-radius:4px;border-radius:4px;background:#dcdcdc;background:-moz-linear-gradient(top, #f8f8f8 0%, #dcdcdc 80%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#dcdcdc));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8f8f8', endColorstr='#dcdcdc',GradientType=0);background:-o-linear-gradient(top, #f8f8f8 0%,#dcdcdc 80%);border:1px outset #dcdcdc;padding-left:4px;padding-right:4px;padding-top:2px;padding-bottom:2px;margin:2px;margin:2px;cursor:pointer;}
+.tbar{margin:0px;width:100%;padding-top:0px;padding-left:0px;padding-right:0px;padding-bottom:0px;border-collapse:separate;background-color:#2c2c2c;}
+.ltbar{padding-left:2px;padding-right:6px;padding-top:3px;padding-bottom:4px;white-space:nowrap;vertical-align:middle;}
+.dtbar{padding-left:0px;padding-right:0px;padding-top:3px;padding-bottom:4px;white-space:nowrap;vertical-align:middle;text-align:right;}
+.rtbar{padding-left:6px;padding-right:2px;padding-top:3px;padding-bottom:4px;white-space:nowrap;vertical-align:middle;text-align:right;}
+.tbaramenu{color:#cccccc;text-decoration:none;white-space:nowrap;}
+.tbarsmenu{font-weight:bold;color:#ffffff;text-decoration:none;white-space:nowrap;}
+.suggest{background-color:#d4e6fc;color:#598edd;border-top:1px;border-bottom:1px;border-left:1px;border-right:1px;border-style:solid;border-top-color:#a2bae7;border-bottom-color:#d1d3d4;border-left-color:#d1d3d4;border-right-color:#d1d3d4;position:absolute;overflow:auto;overflow-x:hidden;padding:0px;margin:0px;cursor:default;}
.suggestTable{border:0px;border-collapse:separate;padding-left:5px;padding-right:5px;padding-top:2px;padding-bottom:2px;margin:0px;}
-.suggestItem{padding-left:2px;padding-top:0px;padding-bottom:0px;padding-right:2px;vertical-align:middle;background-color:#e5ecf9;color:#598edd;}
-.suggestHilighted{padding-left:2px;padding-top:0px;padding-bottom:0px;padding-right:2px;vertical-align:middle;background-color:#598edd;color:#e5ecf9;} \ No newline at end of file
+.suggestItem{padding-left:2px;padding-top:0px;padding-bottom:0px;padding-right:2px;vertical-align:middle;background-color:#d4e6fc;color:#598edd;}
+.suggestHilighted{padding-left:2px;padding-top:0px;padding-bottom:0px;padding-right:2px;vertical-align:middle;background-color:#598edd;color:#d4e6fc;}
+.svgtitle{margin:0px;padding:0px;font-family:"Helvetica Neue", Helvetica;font-style:normal;font-variant:normal;font-size:10px;cursor:default;} \ No newline at end of file
diff --git a/sca-cpp/trunk/modules/js/htdocs/ui.css b/sca-cpp/trunk/modules/js/htdocs/ui.css
index 0842523bf2..b4c27a54e8 100644
--- a/sca-cpp/trunk/modules/js/htdocs/ui.css
+++ b/sca-cpp/trunk/modules/js/htdocs/ui.css
@@ -18,10 +18,10 @@
*/
body {
-margin: 2px; font-family: "Helvetica Neue", Helvetica; font-style: normal; font-variant: normal; font-size: 13px;
+margin-top: 0px; margin-bottom: 2px; margin-left: 2px; margin-right: 2px;
+font-family: "Helvetica Neue", Helvetica; font-style: normal; font-variant: normal; font-size: 13px;
-webkit-text-size-adjust: none;
-webkit-touch-callout: none;
--webkit-tap-highlight-color: rgba(0,0,0,0);
-webkit-user-select: none;
}
@@ -30,7 +30,43 @@ visibility: hidden;
}
.devicewidth {
-position: absolute; top: 0px; left: 0px; right: 0px; height: 5000px; overflow: hidden;
+position: absolute; top: 0px; left: 0px; width: 100%; height: 5000px; overflow: hidden;
+}
+
+.bodydiv {
+position: absolute; top: 0px; left: 0px; width: 100%; height: 5000px; overflow: hidden;
+}
+
+.bodydivloading {
+position: absolute; top: 0px; left: 0px; width: 100%; height: 5000px; overflow: hidden;
+-webkit-transform: translate(100%, 0px); -webkit-backface-visibility: hidden;
+-moz-transform: translate(100%, 0px);
+-ms-transform: translate(100%, 0px);
+transform: translate(100%, 0px);
+}
+
+.bodydivloaded {
+-webkit-transition: -webkit-transform 0.4s linear;
+-moz-transition: -moz-transform 0.4s linear;
+-ms-transition: -ms-transform 0.4s linear;
+transition: transform 0.4s linear;
+position: absolute; top: 0px; left: 0px; width: 100%; height: 5000px; overflow: hidden;
+-webkit-transform: translate3d(0px, 0px, 0px); -webkit-backface-visibility: hidden;
+-moz-transform: translate(0px, 0px);
+-ms-transform: translate(0px, 0px);
+transform: translate(0px, 0px);
+}
+
+.bodydivunloaded {
+-webkit-transition: -webkit-transform 0.4s linear;
+-moz-transition: -moz-transform 0.4s linear;
+-ms-transition: -ms-transform 0.4s linear;
+transition: transform 0.4s linear;
+position: absolute; top: 0px; left: 0px; width: 100%; height: 5000px; overflow: hidden;
+-webkit-transform: translate3d(-100%, 0px, 0px); -webkit-backface-visibility: hidden;
+-moz-transform: translate(-100%, 0px);
+-ms-transform: translate(-100%, 0px);
+transform: translate(-100%, 0px);
}
table {
@@ -44,31 +80,31 @@ border-bottom: 1px; border-bottom-style: solid; border-color: #dcdcdc;
}
th {
-font-weight: bold; background-color: #e5ecf9; color: #000000; height: 18px;
+font-weight: bold; background-color: #d4e6fc; color: #000000; height: 18px;
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: #a2bae7; border-bottom-color: #d1d3d4; border-left-color: #a2bae7; border-right-color: #a2bae7;
overflow: hidden;
}
.section {
-font-weight: bold; background-color: #e5ecf9; color: #000000; height: 24px; padding-top: 1px; padding-bottom: 0px; padding-left: 2px; padding-right: 2px;
+font-weight: bold; background-color: #d4e6fc; color: #000000; height: 24px; padding-top: 1px; padding-bottom: 0px; padding-left: 2px; padding-right: 2px;
border-top: 1px; border-bottom: 1px; border-left: 0px; border-right: 0px; border-style: solid; border-top-color: #a2bae7; border-bottom-color: #d1d3d4; border-left-color: #a2bae7; border-right-color: #a2bae7;
overflow: hidden;
}
.hsection {
width: 100%; height: 50px;
-border-top: 0px; border-bottom: 1px; border-left: 0px; border-right: 0px; border-style: solid; border-bottom-color: #000000; background-color: #ffffff;
-padding: 0px; margin-bottom: 4px; margin-left: auto; margin-right: auto; text-align: center;
+border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 0px; border-style: solid; border-bottom-color: #000000; background-color: #ffffff;
+padding: 0px; margin-bottom: 0px; margin-left: auto; margin-right: auto; text-align: center;
}
.fsection{
width: 100%; height: 50px; border-top: 0px; border-bottom: 0px; border-left: 0px; border-right: 0px; border-style: solid; border-top-color: #a2bae7;
-padding: 0px; margin-top: 4px; margin-left: auto; margin-right: auto; text-align: center;
+padding: 0px; margin-top: 0px; margin-left: auto; margin-right: auto; text-align: center;
}
.text {
-padding-top: 3px; padding-bottom: 4px; vertical-align: middle;
+padding-top: 3px; padding-bottom: 4px; vertical-align: middle; white-space: nowrap;
}
.thl {
@@ -156,35 +192,35 @@ border: 0px;
}
a:link {
-color: #598edd; text-decoration: none;
+color: #598edd; text-decoration: none; white-space: nowrap;
}
a:visited {
-color: #598edd; text-decoration: none;
+color: #598edd; text-decoration: none; white-space: nowrap;
}
.amenu {
-color: #598edd; text-decoration: none;
+color: #598edd; text-decoration: none; white-space: nowrap;
}
.smenu {
-font-weight: bold; color: #000000; text-decoration: none;
+font-weight: bold; color: #000000; text-decoration: none; white-space: nowrap;
}
h1 {
-font-size: 150%; font-weight: bold; vertical-align: middle; margin-top: 5px; margin-bottom: 5px; margin-left: 2px; margin-right: 2px;
+font-size: 150%; font-weight: bold; vertical-align: middle; margin-top: 5px; margin-bottom: 5px; margin-left: 2px; margin-right: 2px; white-space: nowrap;
}
h2 {
-font-size: 120%; font-weight: bold; vertical-align: middle; margin-top: 5px; margin-bottom: 5px; margin-left: 2px; margin-right: 2px;
+font-size: 120%; font-weight: bold; vertical-align: middle; margin-top: 5px; margin-bottom: 5px; margin-left: 2px; margin-right: 2px; white-space: nowrap;
}
.hd1 {
-font-size: 150%; font-weight: bold;
+font-size: 150%; font-weight: bold; white-space: nowrap;
}
.hd2 {
-font-size: 120%; font-weight: bold;
+font-size: 120%; font-weight: bold; white-space: nowrap;
}
img {
@@ -206,10 +242,10 @@ padding-left: 0px; padding-right: 0px; padding-top: 0px; padding-bottom: 0px;
-webkit-border-radius: 4px;
border-radius: 4px;
background: #96d333;
-background: -moz-linear-gradient(top, #f8f8f8 0%, #96d333 100%);
-background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#96d333));
+background: -moz-linear-gradient(top, #f8f8f8 0%, #96d333 80%);
+background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#96d333));
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f8f8f8', endColorstr='#96d333',GradientType=0 );
-background: -o-linear-gradient(top, #f8f8f8 0%,#96d333 100%);
+background: -o-linear-gradient(top, #f8f8f8 0%,#96d333 80%);
border: 1px outset #dcdcdc;
padding-left: 4px; padding-right: 4px; padding-top: 2px; padding-bottom: 2px; margin: 2px;
cursor: pointer;
@@ -219,10 +255,10 @@ cursor: pointer;
-webkit-border-radius: 4px;
border-radius: 4px;
background: #96d333;
-background: -moz-linear-gradient(top, #f8f8f8 0%, #96d333 100%);
-background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#96d333));
+background: -moz-linear-gradient(top, #f8f8f8 0%, #96d333 80%);
+background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#96d333));
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f8f8f8', endColorstr='#96d333',GradientType=0 );
-background: -o-linear-gradient(top, #f8f8f8 0%,#96d333 100%);
+background: -o-linear-gradient(top, #f8f8f8 0%,#96d333 80%);
border: 1px outset #dcdcdc;
padding-left: 4px; padding-right: 4px; padding-top: 2px; padding-bottom: 2px; margin: 2px;
cursor: pointer;
@@ -232,10 +268,10 @@ cursor: pointer;
-webkit-border-radius: 4px;
border-radius: 4px;
background: #598edd;
-background: -moz-linear-gradient(top, #f8f8f8 0%, #598edd 100%);
-background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#598edd));
+background: -moz-linear-gradient(top, #f8f8f8 0%, #598edd 80%);
+background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#598edd));
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f8f8f8', endColorstr='#598edd',GradientType=0 );
-background: -o-linear-gradient(top, #f8f8f8 0%,#598edd 100%);
+background: -o-linear-gradient(top, #f8f8f8 0%,#598edd 80%);
border: 1px outset #dcdcdc;
padding-left: 4px; padding-right: 4px; padding-top: 2px; padding-bottom: 2px; margin: 2px;
cursor: pointer;
@@ -245,10 +281,10 @@ cursor: pointer;
-webkit-border-radius: 4px;
border-radius: 4px;
background: #d03f41;
-background: -moz-linear-gradient(top, #f8f8f8 0%, #d03f41 100%);
-background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#d03f41));
+background: -moz-linear-gradient(top, #f8f8f8 0%, #d03f41 80%);
+background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#d03f41));
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f8f8f8', endColorstr='#d03f41',GradientType=0 );
-background: -o-linear-gradient(top, #f8f8f8 0%,#d03f41 100%);
+background: -o-linear-gradient(top, #f8f8f8 0%,#d03f41 80%);
border: 1px outset #dcdcdc;
padding-left: 4px; padding-right: 4px; padding-top: 2px; padding-bottom: 2px; margin: 2px;
cursor: pointer;
@@ -258,10 +294,10 @@ cursor: pointer;
-webkit-border-radius: 4px;
border-radius: 4px;
background: #ffbb00;
-background: -moz-linear-gradient(top, #f8f8f8 0%, #ffbb00 100%);
-background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#ffbb00));
+background: -moz-linear-gradient(top, #f8f8f8 0%, #ffbb00 80%);
+background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#ffbb00));
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f8f8f8', endColorstr='#ffbb00',GradientType=0 );
-background: -o-linear-gradient(top, #f8f8f8 0%,#ffbb00 100%);
+background: -o-linear-gradient(top, #f8f8f8 0%,#ffbb00 80%);
border: 1px outset #dcdcdc;
padding-left: 4px; padding-right: 4px; padding-top: 2px; padding-bottom: 2px; margin: 2px;
cursor: pointer;
@@ -271,10 +307,10 @@ cursor: pointer;
-webkit-border-radius: 4px;
border-radius: 4px;
background: #dcdcdc;
-background: -moz-linear-gradient(top, #f8f8f8 0%, #dcdcdc 100%);
-background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dcdcdc));
+background: -moz-linear-gradient(top, #f8f8f8 0%, #dcdcdc 80%);
+background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(80%,#dcdcdc));
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f8f8f8', endColorstr='#dcdcdc',GradientType=0 );
-background: -o-linear-gradient(top, #f8f8f8 0%,#dcdcdc 100%);
+background: -o-linear-gradient(top, #f8f8f8 0%,#dcdcdc 80%);
border: 1px outset #dcdcdc;
padding-left: 4px; padding-right: 4px; padding-top: 2px; padding-bottom: 2px; margin: 2px;
margin: 2px;
@@ -282,23 +318,32 @@ cursor: pointer;
}
.tbar {
-margin: 0px; width: 100%; padding-top: 0px; padding-left: 0px; padding-right: 0px; padding-bottom: 3px; border-bottom: 1px solid #a2bae7; border-collapse: separate;
+margin: 0px; width: 100%; padding-top: 0px; padding-left: 0px; padding-right: 0px; padding-bottom: 0px; border-collapse: separate;
+background-color: #2c2c2c;
}
.ltbar {
-padding-left: 2px; padding-top: 2px; padding-right: 6px; white-space: nowrap; vertical-align: middle;
+padding-left: 2px; padding-right: 6px; padding-top: 3px; padding-bottom: 4px; white-space: nowrap; vertical-align: middle;
}
.dtbar {
-padding-left: 0px; padding-right: 0px; padding-top: 2px; white-space: nowrap; vertical-align: middle; text-align: right;
+padding-left: 0px; padding-right: 0px; padding-top: 3px; padding-bottom: 4px; white-space: nowrap; vertical-align: middle; text-align: right;
}
.rtbar {
-padding-left: 6px; padding-right: 2px; padding-top: 2px; white-space: nowrap; vertical-align: middle; text-align: right;
+padding-left: 6px; padding-right: 2px; padding-top: 3px; padding-bottom: 4px; white-space: nowrap; vertical-align: middle; text-align: right;
+}
+
+.tbaramenu {
+color: #cccccc; text-decoration: none; white-space: nowrap;
+}
+
+.tbarsmenu {
+font-weight: bold; color: #ffffff; text-decoration: none; white-space: nowrap;
}
.suggest {
-background-color: #e5ecf9; color: #598edd;
+background-color: #d4e6fc; color: #598edd;
border-top: 1px; border-bottom: 1px; border-left: 1px; border-right: 1px; border-style: solid; border-top-color: #a2bae7; border-bottom-color: #d1d3d4; border-left-color: #d1d3d4; border-right-color: #d1d3d4;
position: absolute; overflow: auto; overflow-x: hidden; padding: 0px; margin: 0px;
cursor: default;
@@ -309,10 +354,14 @@ border: 0px; border-collapse: separate; padding-left: 5px; padding-right: 5px; p
}
.suggestItem {
-padding-left: 2px; padding-top: 0px; padding-bottom: 0px; padding-right: 2px; vertical-align: middle; background-color: #e5ecf9; color: #598edd;
+padding-left: 2px; padding-top: 0px; padding-bottom: 0px; padding-right: 2px; vertical-align: middle; background-color: #d4e6fc; color: #598edd;
}
.suggestHilighted {
-padding-left: 2px; padding-top: 0px; padding-bottom: 0px; padding-right: 2px; vertical-align: middle; background-color: #598edd; color: #e5ecf9;
+padding-left: 2px; padding-top: 0px; padding-bottom: 0px; padding-right: 2px; vertical-align: middle; background-color: #598edd; color: #d4e6fc;
+}
+
+.svgtitle {
+margin: 0px; padding: 0px; font-family: "Helvetica Neue", Helvetica; font-style: normal; font-variant: normal; font-size: 10px; cursor: default;
}
diff --git a/sca-cpp/trunk/modules/js/htdocs/ui.js b/sca-cpp/trunk/modules/js/htdocs/ui.js
index b5843d8916..7c079e3089 100644
--- a/sca-cpp/trunk/modules/js/htdocs/ui.js
+++ b/sca-cpp/trunk/modules/js/htdocs/ui.js
@@ -29,7 +29,7 @@ var ui = {};
ui.ahref = function(loc, target, html) {
if (target == '_blank')
return '<a href="' + loc + '" target="_blank">' + html + '</a>';
- return '<a href="javascript:void(0)" onclick="window.open(\'' + loc + '\', \'' + target + '\');">' + html + '</a>';
+ return '<a href="javascript:void(0)" onclick="ui.navigate(\'' + loc + '\', \'' + target + '\');">' + html + '</a>';
};
/**
@@ -43,6 +43,9 @@ ui.menu = function(name, href, target) {
this.content = function() {
function complete(uri) {
+ var h = uri.indexOf('#');
+ if (h != -1)
+ return complete(uri.substr(0, h));
var q = uri.indexOf('?');
if (q != -1)
return complete(uri.substr(0, q));
@@ -54,8 +57,8 @@ ui.menu = function(name, href, target) {
}
if (complete(this.href) != complete(window.top.location.pathname))
- return ui.ahref(this.href, this.target, '<span class="amenu">' + this.name + '</span>');
- return ui.ahref(this.href, this.target, '<span class="smenu">' + this.name + '</span>');
+ return ui.ahref(this.href, this.target, '<span class="tbaramenu">' + this.name + '</span>');
+ return ui.ahref(this.href, this.target, '<span class="tbarsmenu">' + this.name + '</span>');
};
}
return new Menu(name, href, target);
@@ -179,17 +182,6 @@ ui.suggest = function(input, suggestFunction) {
};
/**
- * Return the content document of a window.
- */
-ui.content = function(win) {
- if (!isNil(win.document))
- return win.document;
- if (!isNil(win.contentDocument))
- return win.contentDocument;
- return null;
-};
-
-/**
* Return a child element of a node with the given id.
*/
ui.elementByID = function(node, id) {
@@ -231,39 +223,165 @@ ui.queryParams = function() {
};
/**
+ * Return a dictionary of the fragment parameters.
+ */
+ui.fragmentParams = function() {
+ var qp = new Array();
+ var qs = window.location.hash.substring(1).split('&');
+ for (var i = 0; i < qs.length; i++) {
+ var e = qs[i].indexOf('=');
+ if (e > 0)
+ qp[qs[i].substring(0, e)] = unescape(qs[i].substring(e + 1));
+ }
+ return qp;
+};
+
+/**
* Return true if the client is a mobile device.
*/
+ui.mobiledetected = false;
+ui.mobile = false;
ui.isMobile = function() {
+ if (ui.mobiledetected)
+ return ui.mobile;
var ua = navigator.userAgent;
if (ua.match(/iPhone/i) || ua.match(/iPad/i) || ua.match(/Android/i) || ua.match(/Blackberry/i) || ua.match(/WebOs/i))
- return true;
- return false;
+ ui.mobile = true;
+ ui.mobiledetected = true;
+ return ui.mobile;
};
/**
- * Initialize a document after it's loaded.
+ * Initialize a document's body.
+ */
+ui.pagetransitions = false;
+
+ui.initbody = function() {
+ if (ui.isMobile()) {
+ //log('init', window.location);
+
+ // Position the main body div off screen
+ if (ui.pagetransitions) {
+ var bdiv = $('bodydiv');
+ if (!isNil(bdiv)) {
+ bdiv.className = 'bodydivloading';
+ }
+ }
+
+ // Install orientation handler
+ document.body.onorientationchange = ui.onorientationchange;
+ }
+ return true;
+}
+
+/**
+ * Reload the current document when orientation changes.
+ */
+ui.onorientationchange = function() {
+ window.open(window.location, '_self');
+ return true;
+}
+
+/**
+ * Post process a document after it's loaded.
*/
ui.onload = function() {
- // Make the document visible
- document.body.style.visibility = 'visible';
+ // Save the current page location in local storage
+ // (except for login and logout pages)
+ var path = document.location.pathname;
+ if (path.indexOf('/login/') != 0 && path.indexOf('/logout/') != 0)
+ localStorage.setItem('ui.lastvisited', '' + document.location);
- // Install orientation handler
- document.body.onorientationchange = function() {
- window.open(window.location, '_self');
- return true;
- };
+ // Make the document body visible
+ //log('visible', $('bodydiv').className);
+ document.body.style.visibility = 'visible';
+ if (ui.pagetransitions && ui.isMobile()) {
+ //log('onload', window.location);
+
+ // Slide the main body div in
+ setTimeout(function() {
+ var bdiv = $('bodydiv');
+ if (!isNil(bdiv)) {
+ function transitionend(e) {
+ bdiv.removeEventListener('webkitTransitionEnd', transitionend, false);
+ bdiv.removeEventListener('transitionend', transitionend, false);
+ bdiv.className = 'bodydiv';
+ //log('loadtransitionend', window.location);
+ };
+ bdiv.addEventListener('webkitTransitionEnd', transitionend, false);
+ bdiv.addEventListener('transitionend', transitionend, false);
+ //log('loadtransitionstart', window.location);
+ bdiv.className = 'bodydivloaded';
+ }
+ }, 0);
+ }
return true;
};
/**
+ * Navigate to a new document.
+ */
+ui.navigate = function(url, win) {
+
+ function opendoc(url, win) {
+ if (win == '_reload') {
+ window.location = url;
+ return window.location.reload();
+ }
+ return window.open(url, win);
+ }
+
+ if (ui.pagetransitions && ui.isMobile() && win != '_blank') {
+
+ // Slide the main body div out, then open the new document
+ var bdiv = $('bodydiv');
+ if (!isNil(bdiv)) {
+ function transitionend(e) {
+ bdiv.removeEventListener('webkitTransitionEnd', transitionend, false);
+ bdiv.removeEventListener('transitionend', transitionend, false);
+ //log('navigatetransitionend', window.location);
+ return opendoc(url, win);
+ };
+ bdiv.addEventListener('webkitTransitionEnd', transitionend, false);
+ bdiv.addEventListener('transitionend', transitionend, false);
+ //log('navigatetransitionstart', window.location);
+ bdiv.className = 'bodydivunloaded';
+ return true;
+ }
+ }
+
+ return opendoc(url, win);
+}
+
+/**
+ * Pre process a document just before it's unloaded.
+ */
+ui.onbeforeunload = function() {
+
+ if (ui.pagetransitions && ui.isMobile()) {
+
+ // Slide the main body div out
+ var bdiv = $('bodydiv');
+ if (!isNil(bdiv))
+ bdiv.className = 'bodydivunloaded';
+ }
+};
+
+
+/**
+ * Return the last visited page.
+ */
+ui.lastvisited = function() {
+ return localStorage.getItem('ui.lastvisited');
+}
+
+/**
* Convert a CSS position to a numeric position.
*/
ui.numpos = function(p) {
- if (p == '')
- return 0;
- return Number(p.substr(0, p.length - 2));
+ return p == ''? 0 : Number(p.substr(0, p.length - 2));
};
/**
diff --git a/sca-cpp/trunk/modules/js/htdocs/util.js b/sca-cpp/trunk/modules/js/htdocs/util.js
index 4c09b2b13c..fd7005e9c7 100644
--- a/sca-cpp/trunk/modules/js/htdocs/util.js
+++ b/sca-cpp/trunk/modules/js/htdocs/util.js
@@ -35,7 +35,7 @@ function car(l) {
}
function first(l) {
- return car(l);
+ return l[0];
}
function cdr(l) {
@@ -43,27 +43,27 @@ function cdr(l) {
}
function rest(l) {
- return cdr(l);
+ return l.slice(1);
}
function cadr(l) {
- return car(cdr(l));
+ return l[1];
}
function cddr(l) {
- return cdr(cdr(l));
+ return l.slice(2);
}
function caddr(l) {
- return car(cddr(l));
+ return l[2];
}
function cdddr(l) {
- return cdr(cdr(cdr(l)));
+ return l.slice(3);
}
function cadddr(l) {
- return car(cdddr(l));
+ return l[3];
}
function append(a, b) {
@@ -82,33 +82,23 @@ function range(a, b) {
}
function isNil(v) {
- if (v == null || typeof v == 'undefined' || (v.constructor == Array && v.length == 0))
- return true;
- return false;
+ return (v == null || typeof v == 'undefined' || (v.constructor == Array && v.length == 0));
}
function isSymbol(v) {
- if (typeof v == 'string' && v.slice(0, 1) == "'")
- return true;
- return false;
+ return (typeof v == 'string' && v.slice(0, 1) == "'");
}
function isString(v) {
- if (typeof v == 'string' && v.slice(0, 1) != "'")
- return true;
- return false;
+ return (typeof v == 'string' && v.slice(0, 1) != "'");
}
function isList(v) {
- if (v != null && typeof v != 'undefined' && v.constructor == Array)
- return true;
- return false;
+ return (v != null && typeof v != 'undefined' && v.constructor == Array);
}
function isTaggedList(v, t) {
- if (isList(v) && !isNil(v) && car(v) == t)
- return true;
- return false;
+ return (isList(v) && !isNil(v) && car(v) == t);
}
var emptylist = new Array();
@@ -131,10 +121,13 @@ function length(l) {
*/
function assoc(k, l) {
if (isNil(l))
- return mklist();
- if (k == car(car(l)))
- return car(l);
- return assoc(k, cdr(l));
+ return emptylist;
+ var n = l.length;
+ for(var i = 0; i < n; i++) {
+ if (k == car(l[i]))
+ return l[i];
+ }
+ return emptylist;
}
/**
@@ -143,15 +136,24 @@ function assoc(k, l) {
function map(f, l) {
if (isNil(l))
return l;
- return cons(f(car(l)), map(f, cdr(l)));
+ var n = l.length;
+ var a = new Array();
+ for(var i = 0; i < n; i++) {
+ a.push(f(l[i]));
+ }
+ return a;
}
function filter(f, l) {
if (isNil(l))
return l;
- if (f(car(l)))
- return cons(car(l), filter(f, cdr(l)));
- return filter(f, cdr(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;
}
function reduce(f, i, l) {
@@ -245,7 +247,12 @@ function assert(exp) {
function writeStrings(l) {
if (isNil(l))
return '';
- return car(l) + writeStrings(cdr(l));
+ var s = '';
+ var n = l.length;
+ for(var i = 0; i < n; i++) {
+ s = s + l[i];
+ }
+ return s;
}
/**