You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by js...@apache.org on 2013/01/03 08:41:56 UTC
svn commit: r1428193 [2/8] - in /tuscany/sca-cpp/trunk: etc/ hosting/server/
hosting/server/data/apps/me360/ hosting/server/data/apps/nearme/
hosting/server/data/apps/nearme2/ hosting/server/data/apps/new/
hosting/server/data/apps/ourphotos/ hosting/se...
Modified: tuscany/sca-cpp/trunk/hosting/server/htdocs/clone/index.html
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/htdocs/clone/index.html?rev=1428193&r1=1428192&r2=1428193&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/hosting/server/htdocs/clone/index.html (original)
+++ tuscany/sca-cpp/trunk/hosting/server/htdocs/clone/index.html Thu Jan 3 07:41:53 2013
@@ -19,29 +19,24 @@
-->
<div id="bodydiv" class="body">
-<div class="viewform">
+<div id="viewform" class="viewform">
<form id="cloneAppForm">
<table style="width: 100%;">
-<tr><td><b>New App Name:</b></td></tr>
-<tr><td><input type="text" id="appName" class="flatentry" size="15" autocapitalize="off" placeholder="Your app name"/></td></tr>
-<tr><tr><td style="padding-top: 6px;"><b>Icon:</b></td></tr>
-<tr><td><img id="appimg" style="width: 50px; height: 50px; vertical-align: top;"></td></tr>
-<tr><tr><td style="padding-top: 6px;"><b>Title:</b></td></tr>
-<tr><td><input type="text" id="appTitle" class="flatentry" size="30" placeholder="Enter the title of your app" style="width: 300px;"/></td></tr>
-<tr><tr><td style="padding-top: 6px;"><b>Description:</b></td></tr>
-<tr><td><textarea id="appDescription" class="flatentry" 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="graybutton bluebutton" style="font-weight: bold;" value="Clone" title="Clone the app"/>
+<tr><td class="label">New URL:</td></tr>
+<tr><td><span id="hostname" class="readentry"></span><input type="text" id="appName" class="flatentry" size="18" autocapitalize="off" placeholder="New app name"/></td></tr>
+<tr><td style="padding-top: 20px;">
+<input id="cloneAppOKButton" type="submit" class="bluebutton" style="font-weight: bold;" value="Clone" title="Clone this app"/>
<input id="cloneAppCancelButton" type="button" class="graybutton" value="Cancel"/>
</td></tr>
</table>
</form>
+<br/>
</div>
<script type="text/javascript">
-(function() {
+(function clonebody() {
/**
* Get the app name.
@@ -49,20 +44,20 @@
var appname = ui.fragmentParams(location)['app'];
/**
- * Set page titles.
+ * Setup page layout.
*/
-document.title = config.windowtitle() + ' - ' + config.clone() + ' - ' + appname;
-$('viewhead').innerHTML = '<span class="smenu">' + config.clone() + ' ' + appname + '</span>';
-$('cloneAppOKButton').value = config.clone();
-$('cloneAppOKButton').title = config.clone() + ' this app';
-
-/**
- * Set images.
- */
-$('appimg').src = ui.b64img(appcache.get('/public/app.b64'));
+(function layout() {
+ document.title = config.windowtitle() + ' - ' + config.clone() + ' - ' + appname;
+ $('viewhead').innerHTML = '<span class="smenu">' + config.clone() + ' ' + appname + '</span>';
+ if (!ui.isMobile())
+ $('viewform').className = 'viewform flatscrollbars';
+ $('hostname').innerHTML = window.location.hostname + '/';
+ $('cloneAppOKButton').value = config.clone();
+ $('cloneAppOKButton').title = config.clone() + ' this app';
+})();
/**
- * Init service references.
+ * Initialize service references.
*/
var editorComp = sca.component("Editor");
var apps = sca.reference(editorComp, "apps");
@@ -71,50 +66,60 @@ var apps = sca.reference(editorComp, "ap
* The current app entry and corresponding saved XML content.
*/
var appentry;
-var savedappentryxml = '';
+var savedappxml = '';
/**
- * Get and display an app.
+ * Get and display the requested app.
*/
-function getapp(name) {
- if (isNil(name))
+(function getapp() {
+ if (isNil(appname))
return false;
- showStatus('Loading');
+ workingstatus(true);
+ showstatus('Loading');
- return apps.get(name, function(doc) {
+ return apps.get(appname, function(doc) {
// Stop now if we didn't get the app
if (doc == null) {
- showError('App not available');
+ errorstatus('Couldn\'t get the app info');
+ workingstatus(false);
return false;
}
- showOnlineStatus();
- appentry = doc != null? car(elementsToValues(atom.readATOMEntry(mklist(doc)))) : mklist("'entry", mklist("'title", ''), mklist("'id", name));
- $('appTitle').value = cadr(assoc("'title", cdr(appentry)));
- var content = cadr(assoc("'content", cdr(appentry)));
- var description = assoc("'description", content);
- $('appDescription').value = isNil(description) || isNil(cadr(description))? '' : cadr(description);
- savedappentryxml = car(atom.writeATOMEntry(valuesToElements(mklist(appentry))));
+ appentry = doc != null? car(elementsToValues(atom.readATOMEntry(mklist(doc)))) : mklist("'entry", mklist("'title", ''), mklist("'id", appname));
+ var content = cadr(assoc("'content", appentry));
+ savedappxml = car(atom.writeATOMEntry(valuesToElements(mklist(appentry))));
+
+ onlinestatus();
+ workingstatus(false);
return true;
});
-}
+})();
/**
* Save an app.
*/
-function save(name, entryxml) {
- showStatus('Saving');
- savedappentryxml = entryxml;
- apps.put(name, savedappentryxml, function(e) {
+function saveapp(name, entryxml) {
+ workingstatus(true);
+ showstatus('Saving');
+
+ savedappxml = entryxml;
+ apps.put(name, savedappxml, function(e) {
if (e) {
- showStatus('Local copy');
+ if (e.code && e.code == 404) {
+ errorstatus('App name is taken, please pick another name');
+ workingstatus(false);
+ return false;
+ }
+ showstatus('Local copy');
+ workingstatus(false);
return false;
}
- showStatus('Saved');
+ showstatus('Saved');
+ workingstatus(false);
- // Open it in the page editor
- ui.navigate('/#view=page&app=' + name, '_view');
+ // Open the app in the page editor
+ ui.navigate('/#view=info&app=' + name, '_view');
return false;
});
return false;
@@ -124,19 +129,36 @@ function save(name, entryxml) {
* Clone an app.
*/
$('cloneAppForm').onsubmit = function() {
+
+ // Validate app name
var name = $('appName').value;
- if (name == '') {
- showError('Missing app name');
+ if (name.length < 3 || name.length > 10) {
+ errorstatus('App name must be between 3 and 10 characters');
+ return false;
+ }
+ name = name.toLowerCase();
+ var anum = name.split('').reduce(function(p, c, i, a) { return p && ((c >= 'a' && c <= 'z') || (c >= '0' && c<= '9')); }, true);
+ if (!anum) {
+ errorstatus('App name is taken, please pick another name');
+ return false;
+ }
+ if (name.charAt(0) < 'a' || name.charAt(0) > 'z') {
+ errorstatus('App name must start with a letter');
+ return false;
+ }
+
+ // Check reserved app names
+ var reserved = mklist('account', 'app', 'cache', 'clone', 'create', 'delete', 'graph', 'home', 'login', 'new', 'page', 'proxy', 'public', 'private', 'info', 'store');
+ if (!isNil(assoc(name, map(function(r) { return mklist(r, r); }, reserved)))) {
+ errorstatus('App name is taken, please pick another name');
return false;
}
- showStatus('Saving');
// Clone the app
- var title = $('appTitle').value;
- var description = $('appDescription').value;
- appentry = mklist("'entry", mklist("'title", title != ''? title : name), mklist("'id", appname), mklist("'content", mklist("'stats", mklist("'description", description))));
+ showstatus('Modified');
+ appentry = mklist("'entry", mklist("'title", name), mklist("'id", appname), mklist("'author", username));
var entryxml = car(atom.writeATOMEntry(valuesToElements(mklist(appentry))));
- return save(name, entryxml);
+ return saveapp(name, entryxml);
};
/**
@@ -146,11 +168,6 @@ $('cloneAppCancelButton').onclick = func
history.back();
};
-/**
- * Get the current app.
- */
-getapp(appname);
-
})();
</script>
Modified: tuscany/sca-cpp/trunk/hosting/server/htdocs/config.js
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/htdocs/config.js?rev=1428193&r1=1428192&r2=1428193&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/hosting/server/htdocs/config.js (original)
+++ tuscany/sca-cpp/trunk/hosting/server/htdocs/config.js Thu Jan 3 07:41:53 2013
@@ -32,7 +32,7 @@ config.pagetitle = function() {
};
config.hometitle = function() {
- return '<br/><span style="font-weight: bold;">Create SCA Composite Apps</span><br/><br/>';
+ return '<br/><span style="font-weight: bold;">Create SCA Apps</span><br/><br/>';
};
config.clone = function() {
Modified: tuscany/sca-cpp/trunk/hosting/server/htdocs/create/index.html
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/htdocs/create/index.html?rev=1428193&r1=1428192&r2=1428193&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/hosting/server/htdocs/create/index.html (original)
+++ tuscany/sca-cpp/trunk/hosting/server/htdocs/create/index.html Thu Jan 3 07:41:53 2013
@@ -19,43 +19,38 @@
-->
<div id="bodydiv" class="body">
-<div class="viewform">
+<div id="viewform" class="viewform">
<form id="createAppForm">
<table style="width: 100%;">
-<tr><td><b>App Name:</b></td></tr>
-<tr><td><input type="text" id="appName" class="flatentry" size="15" autocapitalize="off" placeholder="Your app name"/></td></tr>
-<tr><tr><td style="padding-top: 6px;"><b>App Icon:</b></td></tr>
-<tr><td><img id="appimg" style="width: 50px; height: 50px; vertical-align: top;"></td></tr>
-<tr><tr><td style="padding-top: 6px;"><b>App Title:</b></td></tr>
-<tr><td><input type="text" id="appTitle" class="flatentry" size="30" placeholder="Enter the title of your app" style="width: 300px;"/></td></tr>
-<tr><tr><td style="padding-top: 6px;"><b>Description:</b></td></tr>
-<tr><td><textarea id="appDescription" class="flatentry" 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="graybutton bluebutton" style="font-weight: bold;" value="Create" title="Create the app"/>
+<tr><td class="label">URL:</td></tr>
+<tr><td><span id="hostname" class="readentry"></span><input type="text" id="appName" class="flatentry" size="18" autocapitalize="off" placeholder="New app name"/></td></tr>
+<tr><td style="padding-top: 20px;">
+<input id="createAppOKButton" type="submit" class="bluebutton" style="font-weight: bold;" value="Create" title="Create the app"/>
<input id="createAppCancelButton" type="button" class="graybutton" value="Cancel"/>
</td></tr>
</table>
</form>
+<br/>
</div>
<script type="text/javascript">
-(function() {
+(function createbody() {
/**
- * Set page titles.
+ * Setup page layout.
*/
-document.title = config.windowtitle() + ' - Create App';
-$('viewhead').innerHTML = '<span class="smenu">Create an App</span>';
-
-/**
- * Set images.
- */
-$('appimg').src = ui.b64img(appcache.get('/public/app.b64'));
+(function layout() {
+ document.title = config.windowtitle() + ' - New App';
+ $('viewhead').innerHTML = '<span class="smenu">New App</span>';
+ if (!ui.isMobile())
+ $('viewform').className = 'viewform flatscrollbars';
+ $('hostname').innerHTML = window.location.hostname + '/';
+})();
/**
- * Init service references.
+ * Initialize service references.
*/
var editorComp = sca.component("Editor");
var apps = sca.reference(editorComp, "apps");
@@ -64,23 +59,32 @@ var apps = sca.reference(editorComp, "ap
* The current app entry and corresponding saved XML content.
*/
var appentry;
-var savedappentryxml = '';
+var savedappxml = '';
/**
* Save an app.
*/
-function save(name, entryxml) {
- showStatus('Saving');
- savedappentryxml = entryxml;
- apps.put(name, savedappentryxml, function(e) {
+function saveapp(name, entryxml) {
+ workingstatus(true);
+ showstatus('Saving');
+
+ savedappxml = entryxml;
+ apps.put(name, savedappxml, function(e) {
if (e) {
- showStatus('Local copy');
+ if (e.code && e.code == 404) {
+ errorstatus('App name is taken, please pick another name');
+ workingstatus(false);
+ return false;
+ }
+ showstatus('Local copy');
+ workingstatus(false);
return false;
}
- showStatus('Saved');
+ showstatus('Saved');
+ workingstatus(false);
- // Open it in the page editor
- ui.navigate('/#view=page&app=' + name, '_view');
+ // Open the app in the page editor
+ ui.navigate('/#view=info&app=' + name, '_view');
return false;
});
return false;
@@ -90,19 +94,36 @@ function save(name, entryxml) {
* Create an app.
*/
$('createAppForm').onsubmit = function() {
+
+ // Validate app name
var name = $('appName').value;
- if (name == '') {
- showError('Missing app name');
+ if (name.length < 3 || name.length > 10) {
+ errorstatus('App name must be between 3 and 10 characters');
+ return false;
+ }
+ name = name.toLowerCase();
+ var anum = name.split('').reduce(function(p, c, i, a) { return p && ((c >= 'a' && c <= 'z') || (c >= '0' && c<= '9')); }, true);
+ if (!anum) {
+ errorstatus('App name can only use numbers and letters');
+ return false;
+ }
+ if (name.charAt(0) < 'a' || name.charAt(0) > 'z') {
+ errorstatus('App name must start with a letter');
+ return false;
+ }
+
+ // Check reserved app names
+ var reserved = mklist('account', 'app', 'cache', 'clone', 'create', 'delete', 'graph', 'home', 'login', 'new', 'page', 'proxy', 'public', 'private', 'info', 'store');
+ if (!isNil(assoc(name, map(function(r) { return mklist(r, r); }, reserved)))) {
+ errorstatus('App name is taken, please pick another name');
return false;
}
- showStatus('Modified');
// Clone the 'new' app template
- var title = $('appTitle').value;
- var description = $('appDescription').value;
- appentry = mklist("'entry", mklist("'title", title != ''? title : name), mklist("'id", 'new'), mklist("'content", mklist("'stats", mklist("'description", description))));
+ showstatus('Modified');
+ appentry = mklist("'entry", mklist("'title", name), mklist("'id", 'new'), mklist("'author", username));
var entryxml = car(atom.writeATOMEntry(valuesToElements(mklist(appentry))));
- return save(name, entryxml);
+ return saveapp(name, entryxml);
};
/**
@@ -115,7 +136,7 @@ $('createAppCancelButton').onclick = fun
/**
* Show the status.
*/
-showOnlineStatus();
+onlinestatus();
})();
</script>
Modified: tuscany/sca-cpp/trunk/hosting/server/htdocs/delete/index.html
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/htdocs/delete/index.html?rev=1428193&r1=1428192&r2=1428193&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/hosting/server/htdocs/delete/index.html (original)
+++ tuscany/sca-cpp/trunk/hosting/server/htdocs/delete/index.html Thu Jan 3 07:41:53 2013
@@ -19,31 +19,32 @@
-->
<div id="bodydiv" class="body">
-<div class="viewform">
+<div id="viewform" class="viewform">
<form id="deleteAppForm">
<table style="width: 100%;">
-<tr><tr><td style="padding-top: 6px;"><b>App Icon:</b></td></tr>
-<tr><td><img id="appimg" style="width: 50px; height: 50px; vertical-align: top;"></td></tr>
-<tr><tr><td style="padding-top: 6px;"><b>App Title:</b></td></tr>
-<tr><td><input type="text" id="appTitle" class="flatentry" size="30" readonly="readonly" style="width: 300px;"/></td></tr>
-<tr><tr><td style="padding-top: 6px;"><b>Author:</b></td></tr>
-<tr><td><span id="appAuthor"></span></td></tr>
-<tr><tr><td style="padding-top: 6px;"><b>Updated:</b></td></tr>
-<tr><td><span id="appUpdated"></span></td></tr>
-<tr><tr><td style="padding-top: 6px;"><b>Description:</b></td></tr>
-<tr><td><textarea id="appDescription" class="flatentry" cols="40" rows="3" readonly="readonly" style="width: 300px;"></textarea></td></tr>
+<tr><tr><td class="label">URL:</td></tr>
+<tr><td><input type="text" id="appURL" class="readentry" size="30" readonly="readonly" placeholder="App URL" style="width: 300px;"/></td></tr>
+<tr><tr><td class="label">Icon:</td></tr>
+<tr><td><img id="appIcon" style="width: 50px; height: 50px; vertical-align: top;"></td></tr>
+<tr><tr><td class="label">Author:</td></tr>
+<tr><td><img id="authorPhoto" style="width: 50px; height: 50px; vertical-align: middle;"><input type="text" id="appAuthor" class="readentry" size="30" readonly="readonly" placeholder="Author of the app" style="width: 248px;"/></td></tr>
+<tr><tr><td class="label">Updated:</td></tr>
+<tr><td><input type="text" id="appUpdated" class="readentry" size="30" readonly="readonly" placeholder="App update date" style="width: 300px;"/></td></tr>
+<tr><tr><td class="label">Description:</td></tr>
+<tr><td><textarea id="appDescription" class="readentry" cols="40" rows="3" readonly="readonly" placeholder="No description for this app" style="width: 300px;"></textarea></td></tr>
<tr><td>
-<input id="deleteAppOKButton" type="submit" class="graybutton bluebutton" style="font-weight: bold;" value="Delete" title="Delete the app"/>
+<input id="deleteAppOKButton" type="submit" class="bluebutton" style="font-weight: bold;" value="Delete" title="Delete the app"/>
<input id="deleteAppCancelButton" type="button" class="graybutton" value="Cancel"/>
</td></tr>
</table>
</form>
+<br/>
</div>
<script type="text/javascript">
-(function() {
+(function deletebody() {
/**
* Get the app name.
@@ -51,18 +52,24 @@
var appname = ui.fragmentParams(location)['app'];
/**
- * Set page titles.
+ * Setup page layout.
*/
-document.title = config.windowtitle() + ' - ' + 'Delete' + ' - ' + appname;
-$('viewhead').innerHTML = '<span class="smenu">Delete ' + appname + '</span>';
+(function layout() {
+ document.title = config.windowtitle() + ' - ' + 'Delete' + ' - ' + appname;
+ $('viewhead').innerHTML = '<span class="smenu">Delete ' + appname + '</span>';
+ if (!ui.isMobile())
+ $('viewform').className = 'viewform flatscrollbars';
+ $('appURL').value = window.location.hostname + '/' + appname + '/';
+})();
/**
* Set images.
*/
-$('appimg').src = ui.b64img(appcache.get('/public/app.b64'));
+$('appIcon').src = ui.b64png(appcache.get('/public/app.b64'));
+$('authorPhoto').src = ui.b64png(appcache.get('/public/user.b64'));
/**
- * Init service references.
+ * Initialize service references.
*/
var editorComp = sca.component("Editor");
var apps = sca.reference(editorComp, "apps");
@@ -73,49 +80,56 @@ var apps = sca.reference(editorComp, "ap
var appentry;
/**
- * Get and display an app.
+ * Get and display the requested app.
*/
-function getapp(name) {
- if (isNil(name))
+(function getapp() {
+ if (isNil(appname))
return false;
- showStatus('Loading');
+ workingstatus(true);
+ showstatus('Loading');
- return apps.get(name, function(doc) {
+ return apps.get(appname, function(doc) {
// Stop now if we didn't get the app
if (doc == null) {
- showError('App not available');
+ errorstatus('Couldn\'t get the app info');
+ workingstatus(false);
return false;
}
- showOnlineStatus();
- appentry = doc != null? car(elementsToValues(atom.readATOMEntry(mklist(doc)))) : mklist("'entry", mklist("'title", ''), mklist("'id", name));
- $('appTitle').value = cadr(assoc("'title", cdr(appentry)));
- $('appAuthor').innerHTML = cadr(assoc("'author", cdr(appentry)));
- $('appUpdated').innerHTML = cadr(assoc("'updated", cdr(appentry)));
- var content = cadr(assoc("'content", cdr(appentry)));
+ appentry = doc != null? car(elementsToValues(atom.readATOMEntry(mklist(doc)))) : mklist("'entry", mklist("'title", ''), mklist("'id", appname));
+ var author = cadr(assoc("'author", appentry));
+ $('appAuthor').value = author.split('@')[0];
+ $('appUpdated').value = xmldatetime(cadr(assoc("'updated", appentry))).toLocaleDateString();
+ var content = cadr(assoc("'content", appentry));
var description = assoc("'description", content);
$('appDescription').value = isNil(description) || isNil(cadr(description))? '' : cadr(description);
+
+ onlinestatus();
+ workingstatus(false);
return true;
});
-}
+})();
/**
- * Delete an app.
+ * Delete the app.
*/
$('deleteAppForm').onsubmit = function() {
- showStatus('Deleting');
+ workingstatus(true);
+ showstatus('Deleting');
// Delete the app
apps.del(appname, function(e) {
if (e) {
- showStatus('Local copy');
+ showstatus('Local copy');
+ workingstatus(false);
return false;
}
- showOnlineStatus();
+ onlinestatus();
+ workingstatus(false);
// Return to the app store
- ui.navigate('/#view=store', '_view');
+ ui.navigate('/#view=store&category=myapps&idx=5', '_view');
return false;
});
return false;
@@ -128,11 +142,6 @@ $('deleteAppCancelButton').onclick = fun
history.back();
};
-/**
- * Get the current app.
- */
-getapp(appname);
-
})();
</script>
Added: tuscany/sca-cpp/trunk/hosting/server/htdocs/favicon-16.xcf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/htdocs/favicon-16.xcf?rev=1428193&view=auto
==============================================================================
Files tuscany/sca-cpp/trunk/hosting/server/htdocs/favicon-16.xcf (added) and tuscany/sca-cpp/trunk/hosting/server/htdocs/favicon-16.xcf Thu Jan 3 07:41:53 2013 differ
Added: tuscany/sca-cpp/trunk/hosting/server/htdocs/favicon-32.xcf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/htdocs/favicon-32.xcf?rev=1428193&view=auto
==============================================================================
Files tuscany/sca-cpp/trunk/hosting/server/htdocs/favicon-32.xcf (added) and tuscany/sca-cpp/trunk/hosting/server/htdocs/favicon-32.xcf Thu Jan 3 07:41:53 2013 differ
Modified: tuscany/sca-cpp/trunk/hosting/server/htdocs/favicon.ico
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/htdocs/favicon.ico?rev=1428193&r1=1428192&r2=1428193&view=diff
==============================================================================
Files tuscany/sca-cpp/trunk/hosting/server/htdocs/favicon.ico (original) and tuscany/sca-cpp/trunk/hosting/server/htdocs/favicon.ico Thu Jan 3 07:41:53 2013 differ
Modified: tuscany/sca-cpp/trunk/hosting/server/htdocs/graph/index.html
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/htdocs/graph/index.html?rev=1428193&r1=1428192&r2=1428193&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/hosting/server/htdocs/graph/index.html (original)
+++ tuscany/sca-cpp/trunk/hosting/server/htdocs/graph/index.html Thu Jan 3 07:41:53 2013
@@ -19,13 +19,13 @@
-->
<div id="bodydiv" class="body">
-<div id="contentdiv" class="viewcontent" style="width: 2500px;">
-<div id="graphdiv" class="graphdiv" style="top: 0px; left: -2500px; width: 5000px; height: 5000px;"></div>
-<div id="playdiv" style="position: absolute; top: 0x; left: 0px; width: 2500px; height: 5000px; visibility: hidden"></div>
+<div id="viewcontent" class="viewcontent" style="width: 100%;">
+<div id="graphdiv" class="graphcontent" style="top: 0px; left: -2500px; width: 5000px; height: 5000px;"></div>
+<div id="playdiv" style="position: absolute; top: 0x; left: 0px; width: 2500px; height: 5000px; display: none"></div>
</div>
<script type="text/javascript">
-(function() {
+(function graphbody() {
/**
* Get the current app name.
@@ -49,11 +49,14 @@ document.title = config.windowtitle() +
* Set header div.
*/
$('viewhead').innerHTML = '<span id="appTitle" class="cmenu">' + appname + '</span>' +
-'<input type="button" id="deleteCompButton" title="Delete a component" class="graybutton redbutton plusminus" style="position: absolute; top: 4px; left: 5px;" disabled="true" value="-"/>' +
-'<span style="position: absolute; top: 0px; left: 45px; right: 115px; padding: 0px; background: transparent;"><input id="compValue" type="text" value="" class="flatentry" title="Component value" autocapitalize="off" placeholder="Value" style="position: absolute; left: 0px; top: 4px; width: 100%; visibility: hidden;" readonly="readonly"/></span>' +
+'<input type="button" id="deleteCompButton" title="Delete a component" class="redbutton plusminus" style="position: absolute; top: 4px; left: 5px;" disabled="true" value="-"/>' +
+'<span style="position: absolute; top: 0px; left: 45px; right: 115px; padding: 0px; background: transparent;"><input id="compValue" type="text" value="" class="flatentry" title="Component value" autocapitalize="off" placeholder="Value" style="position: absolute; left: 0px; top: 4px; width: 100%; display: none;" readonly="readonly"/></span>' +
'<input type="button" id="playCompButton" title="View component value" class="graybutton plusminus" style="position: absolute; top: 4px; right: 75px;" disabled="true" value=">"/>' +
-'<input type="button" id="copyCompButton" title="Copy a component" class="graybutton bluebutton" style="position: absolute; top: 4px; right: 40px;" disabled="true" value="C"/>' +
-'<input type="button" id="addCompButton" title="Add a component" class="graybutton bluebutton plusminus" style="position: absolute; top: 4px; right: 5px;" disabled="true" value="+"/>';
+'<input type="button" id="copyCompButton" title="Copy a component" class="bluebutton" style="position: absolute; top: 4px; right: 40px;" disabled="true" value="C"/>' +
+'<input type="button" id="addCompButton" title="Add a component" class="bluebutton plusminus" style="position: absolute; top: 4px; right: 5px;" disabled="true" value="+"/>';
+
+if (!ui.isMobile())
+ $('viewcontent').className = 'viewcontent flatscrollbars';
/**
* Track the current app composite, author, and saved XML content.
@@ -159,8 +162,8 @@ graph.mkedit = function(graphdiv, pos, a
graph.dragged = false;
graph.selected = null;
cvalue.readOnly = true;
- cvalue.style.visibility = 'hidden';
- atitle.style.visibility = 'visible';
+ cvalue.style.display = 'none';
+ atitle.style.display = 'block';
ccopy.disabled = true;
cdelete.disabled = true;
cadd.disabled = !editable;
@@ -182,6 +185,54 @@ graph.mkedit = function(graphdiv, pos, a
}
/**
+ * Render component move animation.
+ */
+ function onmoveanimation() {
+ //debug('onmoveanimation');
+
+ // Stop animation if we're not dragging an element anymore
+ if (graph.dragging == null)
+ return true;
+
+ // Request the next animation frame
+ ui.animation(onmoveanimation);
+
+ // Nothing to do if the selected component has not moved
+ if (graph.moveX == graph.dragX && graph.moveY == graph.dragY)
+ return true;
+
+ // Remember that the selected component has been dragged
+ graph.dragged = true;
+
+ // Cut wire to the dragged component
+ if (graph.dragging.parentNode != graphdiv) {
+ var compos = scdl.composite(graphdiv.compos);
+ setElement(compos, graph.sortcompos(graph.cutwire(graph.dragging, compos, graphdiv)));
+
+ // Bring component to the top
+ graph.bringtotop(graph.dragging, graphdiv);
+ }
+
+ // Calculate new position of the dragged component
+ var gpos = graph.relpos(graph.dragging);
+ var newX = gpos.x + (graph.moveX - graph.dragX);
+ var newY = gpos.y + (graph.moveY - graph.dragY);
+ if (newX >= graph.palcx)
+ graph.dragX = graph.moveX
+ else
+ newX = graph.palcx;
+ if (newY >= 0)
+ graph.dragY = graph.moveY;
+ else
+ newY = 0;
+
+ // Move it
+ graph.move(graph.dragging, graph.mkpath().pos(newX, newY));
+
+ return false;
+ };
+
+ /**
* Handle a mouse down or touch start event.
*/
function onmousedown(e) {
@@ -209,6 +260,9 @@ graph.mkedit = function(graphdiv, pos, a
graph.dragX = pos.screenX;
graph.dragY = pos.screenY;
+ // Start move animation
+ ui.animation(onmoveanimation);
+
e.preventDefault();
return true;
};
@@ -393,69 +447,28 @@ graph.mkedit = function(graphdiv, pos, a
/**
* Handle a mouse or touch move event.
*/
- function onmousemove(e) {
- if (graph.dragging == null)
- return true;
-
- // 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 != graphdiv) {
- var compos = scdl.composite(graphdiv.compos);
- setElement(compos, graph.sortcompos(graph.cutwire(graph.dragging, compos, graphdiv)));
-
- // Bring component to the top
- graph.bringtotop(graph.dragging, graphdiv);
- }
-
- // Calculate new position of dragged element
- var gpos = graph.relpos(graph.dragging);
- var newX = gpos.x + (graph.moveX - graph.dragX);
- var newY = gpos.y + (graph.moveY - graph.dragY);
- if (newX >= graph.palcx)
- graph.dragX = graph.moveX
- else
- newX = graph.palcx;
- if (newY >= 0)
- graph.dragY = graph.moveY;
- else
- newY = 0;
-
- // Move the dragged element
- graph.move(graph.dragging, graph.mkpath().pos(newX, newY));
-
- return false;
- };
-
if (!ui.isMobile()) {
window.onmousemove = function(e) {
//debug('onmousemove');
- // Remember mouse position
+ // Record mouse position
graph.moveX = e.screenX;
graph.moveY = e.screenY;
-
- return onmousemove(e);
+ if (graph.dragging == null)
+ return true;
+ return false;
}
} else {
graphdiv.ontouchmove = function(e) {
//debug('ontouchmove');
- // Remember touch position
+ // Record 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)
+ if (graph.dragging == null)
return true;
-
- return onmousemove(e);
+ return false;
}
}
@@ -465,7 +478,7 @@ graph.mkedit = function(graphdiv, pos, a
function onvaluechange() {
if (graph.selected == null)
return false;
- if (graphdiv.parentNode.style.visibility == 'hidden')
+ if (graphdiv.parentNode.style.display == 'none')
return false;
// Change component name and refactor references to it
@@ -496,8 +509,8 @@ graph.mkedit = function(graphdiv, pos, a
graph.setproperty(graph.selected.comp, cvalue.value);
var hasprop = graph.hasproperty(graph.selected.comp);
cvalue.readOnly = (hasprop? false : true) || !editable;
- cvalue.style.visibility = hasprop? 'visible' : 'hidden';
- atitle.style.visibility = hasprop? 'hidden' : 'visible';
+ cvalue.style.display = hasprop? 'block' : 'none';
+ atitle.style.display = hasprop? 'none' : 'block';
cvalue.value = graph.property(graph.selected.comp);
// Refresh the composite
@@ -597,10 +610,11 @@ graph.mkedit = function(graphdiv, pos, a
return false;
};
- // Create a hidden SVG element to help compute the width
- // of component and reference titles
+ // Create a hidden element to help compute the width of
+ // component and reference titles
graph.offtitles = document.createElement('span');
graph.offtitles.style.visibility = 'hidden';
+ graph.offtitles.style.display = 'block';
graph.offtitles.position = 'absolute';
graph.offtitles.top = -500;
graph.offtitles.width = 500;
@@ -792,8 +806,8 @@ graph.compselect = function(g, s, atitle
if (isNil(g) || !s) {
cvalue.value = '';
cvalue.readOnly = true;
- cvalue.style.visibility = 'hidden';
- atitle.style.visibility = 'visible';
+ cvalue.style.display = 'none';
+ atitle.style.display = 'block';
ccopy.disabled = true;
cdelete.disabled = true;
if (isNil(g))
@@ -806,8 +820,8 @@ graph.compselect = function(g, s, atitle
cvalue.value = graph.hasproperty(g.comp)? graph.property(g.comp) : g.id;
cvalue.readOnly = false || !editable;
- cvalue.style.visibility = 'visible';
- atitle.style.visibility = 'hidden';
+ cvalue.style.display = 'block';
+ atitle.style.display = 'none';
ccopy.disabled = false || !editable;
cdelete.disabled = false || !editable;
@@ -1817,13 +1831,15 @@ var bpalette = null;
function getapp(name, g) {
if (isNil(name))
return false;
- showStatus('Loading');
+ workingstatus(true);
+ showstatus('Loading');
return composites.get(name, function(doc) {
// Stop now if we didn't get a composite
if (doc == null) {
- showError('App not available');
+ errorstatus('Couldn\'t get the app info');
+ workingstatus(false);
return false;
}
@@ -1849,7 +1865,12 @@ function getapp(name, g) {
author = elementValue(namedElementChild("'author", composentry));
editable = author == username;
cadd.disabled = !editable;
- showStatus(editable? onlineStatus() : 'Read only');
+ if (editable)
+ onlinestatus();
+ else
+ showstatus('Read only');
+
+ workingstatus(false);
return true;
});
}
@@ -1912,17 +1933,21 @@ function installpalette(name, pos, g, bg
* Save the current composite.
*/
function save(savexml) {
- showStatus('Saving');
+ workingstatus(true);
+ showstatus('Saving');
+
savedcomposxml = savexml;
var entry = '<?xml version="1.0" encoding="UTF-8"?>\n' + '<entry xmlns="http://www.w3.org/2005/Atom">' +
'<title type="text">' + appname + '</title><id>' + appname + '</id><author><email>' + author + '</email></author>' +
'<content type="application/xml">' + savedcomposxml + '</content></entry>';
composites.put(appname, entry, function(e) {
if (e) {
- showStatus('Local copy');
+ showstatus('Local copy');
+ workingstatus(false);
return false;
}
- showStatus('Saved');
+ showstatus('Saved');
+ workingstatus(false);
return false;
});
return true;
@@ -1938,17 +1963,17 @@ function oncomposchange(prop) {
var newxml = car(writeXML(composite, false));
if (savedcomposxml == newxml)
return false;
- showStatus('Modified');
+ showstatus('Modified');
// Save property changes right away
if (prop)
return save(newxml);
// Autosave other changes after 1 second
- showStatus('Modified');
- setTimeout(function() {
+ showstatus('Modified');
+ ui.delay(function autosave() {
if (savedcomposxml == newxml) {
- showStatus('Saved');
+ showstatus('Saved');
return false;
}
return save(newxml);
@@ -1997,7 +2022,7 @@ function showdata(gcomp) {
cplay.value = '<';
gvisible = false;
pdiv.innerHTML = '';
- pdiv.style.visibility = 'visible';
+ pdiv.style.display = 'block';
// Get the component result data
var comp = sca.component(gcomp.id, appname);
@@ -2030,9 +2055,9 @@ function showdata(gcomp) {
return displaydata(t, '100%');
});
- setTimeout(function() {
- graphdiv.style.visibility = 'hidden'
- }, 0);
+ ui.async(function hidegraphdiv() {
+ graphdiv.style.display = 'none'
+ });
return true;
}
@@ -2043,13 +2068,13 @@ function showgraph(gcomp) {
if (gvisible)
return true;
cplay.value = '>';
- graphdiv.style.visibility = 'visible'
+ graphdiv.style.display = 'block'
gvisible = true;
graph.compselect(gcomp, true, atitle, cvalue, ccopy, cdelete);
- setTimeout(function() {
- pdiv.style.visibility = 'hidden';
+ ui.async(function hideplaydiv() {
+ pdiv.style.display = 'none';
pdiv.innerHTML = '';
- }, 0);
+ });
return true;
}
Modified: tuscany/sca-cpp/trunk/hosting/server/htdocs/home/index.html
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/htdocs/home/index.html?rev=1428193&r1=1428192&r2=1428193&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/hosting/server/htdocs/home/index.html (original)
+++ tuscany/sca-cpp/trunk/hosting/server/htdocs/home/index.html Thu Jan 3 07:41:53 2013
@@ -19,7 +19,7 @@
-->
<div id="bodydiv" class="body">
-<div class="viewcontent" style="margin-left: auto; margin-right: auto; text-align: center;">
+<div id="viewcontent" class="viewcontent" style="margin-left: auto; margin-right: auto; text-align: center;">
<br/>
<div id="hometitle" style="font-size: 28px;"></div>
@@ -29,22 +29,27 @@
<div id="homeanimation" style="width: 320px; height: 280px; padding: 0px; margin: 0px auto;"></div>
-->
-<input type="button" class="graybutton bluebutton" style="font-size: 21px; padding: 10px; height: 50px;" id="getstarted" title="Get Started" value="Get Started"/>
+<input type="button" class="bluebutton" style="font-size: 21px; padding: 10px; height: 50px;" id="getstarted" title="Get Started" value="Get Started"/>
<br/><br/>
-<div class="note">Requires Safari 5+, Chrome 11+, Firefox 4+, IE 9+</div>
+<div class="note">Requires Safari 5+, Chrome 11+, Firefox 4+ or IE 9+</div>
+<br/>
</div>
<script type="text/javascript">
-(function() {
+(function homebody() {
/**
- * Set page titles.
+ * Setup page layout.
*/
-document.title = config.windowtitle();
-$('viewhead').innerHTML = '<span class="bcmenu">' + config.pagetitle() + '</span>';
-$('hometitle').innerHTML = config.hometitle();
+(function layout() {
+ document.title = config.windowtitle();
+ $('viewhead').innerHTML = '<span class="bcmenu">' + config.pagetitle() + '</span>';
+ $('hometitle').innerHTML = config.hometitle();
+ if (!ui.isMobile())
+ $('viewcontent').className = 'viewcontent flatscrollbars';
+})();
$('getstarted').onclick = function() {
return ui.navigate('/#view=store', '_view');
@@ -53,22 +58,24 @@ $('getstarted').onclick = function() {
/**
* Display animation.
*/
-var anim = $('homeanimation');
-if (!isNil(anim)) {
- anim.style.background = 'url(\'' + ui.b64img(appcache.get('/home/home.b64')) + '\')';
- var bgpos = 0;
- setInterval(function() {
- bgpos = bgpos -280;
- if (bgpos == -2800)
- bgpos = 0;
- anim.style.backgroundPosition = '0px ' + ui.pixpos(bgpos);
- }, 2000);
-}
+(function homeanimation() {
+ var anim = $('homeanimation');
+ if (!isNil(anim)) {
+ anim.style.background = 'url(\'' + ui.b64png(appcache.get('/home/home.b64')) + '\')';
+ var bgpos = 0;
+ setInterval(function homeanimation() {
+ bgpos = bgpos -280;
+ if (bgpos == -2800)
+ bgpos = 0;
+ anim.style.backgroundPosition = '0px ' + ui.pixpos(bgpos);
+ }, 2000);
+ }
+})();
/**
* Show the status.
*/
-showOnlineStatus();
+onlinestatus();
})();
</script>
Modified: tuscany/sca-cpp/trunk/hosting/server/htdocs/index.html
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/htdocs/index.html?rev=1428193&r1=1428192&r2=1428193&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/hosting/server/htdocs/index.html (original)
+++ tuscany/sca-cpp/trunk/hosting/server/htdocs/index.html Thu Jan 3 07:41:53 2013
@@ -17,50 +17,69 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html manifest="/cache-manifest.cmf">
+<html>
<head>
+<!-- Firebug inspector -->
+<!--
+<script type="text/javascript" src="https://getfirebug.com/releases/lite/1.3/firebug-lite.js"></script>
+-->
+<!-- Weinre inspector -->
+<!--
+<script src="http://www.example.com:9998/target/target-script-min.js#anonymous"></script>
+-->
<title></title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"/>
+<!--
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
-<link rel="apple-touch-icon" href="/public/touchicon.png"/>
+-->
+<link rel="apple-touch-icon-precomposed" href="/public/touchicon.png"/>
<base href="/"/>
<script type="text/javascript">
-(function() {
+try {
+
+(function roothead() {
window.appcache = {};
/**
* Get and cache a resource.
*/
-appcache.get = function(uri) {
+appcache.get = function(uri, mode) {
var h = uri.indexOf('#');
var u = h == -1? uri : uri.substring(0, h);
// Get resource from local storage first
var ls = window.lstorage || localStorage;
- var item = null;
- try { item = ls.getItem(u); } catch(e) {}
- if (item != null && item != '')
- return item;
+ if (mode != 'remote') {
+ var item = null;
+ try { item = ls.getItem('ui.r.' + u); } catch(e) {}
+ if (item != null && item != '')
+ return item;
+ if (mode == 'local')
+ return null;
+ }
// Get resource from network
//if (window.debug) debug('appcache.get', u);
var http = new XMLHttpRequest();
- http.open("GET", u, false);
+ http.open("GET", mode == 'remote'? (u + '?t=' + new Date().getTime() + '&r=' + Math.random()) : u, false);
http.setRequestHeader("Accept", "*/*");
http.send(null);
if (http.status == 200) {
- if (http.getResponseHeader("X-Login") != null) {
+ var xl = http.getResponseHeader("X-Login");
+ if (xl != null && xl != '') {
if (window.debug) debug('http error', u, 'X-Login');
// Redirect to login page if not signed in
document.location = '/login/';
return null;
- } else if (http.responseText == '' || http.getResponseHeader("Content-Type") == null) {
+ }
+ var ct = http.getResponseHeader("Content-Type");
+ if (http.responseText == '' || ct == null || ct == '') {
if (window.debug) debug('http error', u, 'No-Content');
return null;
}
- try { ls.setItem(u, http.responseText); } catch(e) {}
+ try { ls.setItem('ui.r.' + u, http.responseText); } catch(e) {}
return http.responseText;
}
if (window.debug) debug('http error', u, http.status, http.statusText);
@@ -83,82 +102,68 @@ appcache.remove = function(uri) {
/**
* Load Javascript and CSS.
*/
-(function() {
+(function rootboot() {
-var bootjs = document.createElement('script');
-bootjs.type = 'text/javascript';
-bootjs.text = appcache.get('/all-min.js');
-document.head.appendChild(bootjs);
-document.head.appendChild(ui.declareCSS(appcache.get('/ui-min.css')));
+window.eval.call(window, 'try {\n' + appcache.get('/all-min.js') + '\n' + appcache.get('/config-min.js') + '\n} catch(e) { console.log(e.stack); throw e; }\n');
+ui.includeCSS(appcache.get('/ui-min.css'));
// Disable cache for testing
//lstorage.enabled = false;
})();
-/**
- * Redirect to login page if not signed in.
- */
-(function() {
-
-if (document.location.protocol == 'https:' && !hasauthcookie())
- document.location = '/login/';
-
-})();
+} catch(e) {
+ if (window.debug) debug(e.stack);
+ throw e;
+}
</script>
</head>
<body class="delayed">
-<div id="mainbodydiv" class="mainbody">
-<div id="headdiv" class="hsection">
-<script type="text/javascript">
-(function() {
-
-$('headdiv').appendChild(ui.declareScript(appcache.get('/config-min.js')));
-
-})();
-</script>
+<div id="menucontainer" class="tbarmenu">
+<div id="menu"></div>
</div>
-<div id="menubackground" class="tbarbackground fixed"></div>
-<div id="menu" class="tbarmenu fixed"></div>
+<div id="viewheadcontainer" class="viewhead">
+<div id="viewhead"></div>
+</div>
-<div id="viewheadbackground" class="viewheadbackground fixed"></div>
-<div id="viewhead" class="viewhead fixed"></div>
+<div id="working" class="working" style="display: none;"></div>
<div id="viewcontainer"></div>
-<div id="viewfootbackground" class="viewfootbackground fixed"></div>
-<div id="viewfoot" class="viewfoot fixed"></div>
-<div id="status" class="status fixed" style="visibility: hidden;"></div>
+<div id="viewfootcontainer" class="viewfoot">
+<div id="viewfoot"></div>
+<div id="status"></div>
+</div>
+
+<div id="installer" class="installer"></div>
<script type="text/javascript">
-(function() {
+try {
-/**
- * Init service references.
- */
-var editorComp = sca.component("Editor");
-var user= sca.defun(sca.reference(editorComp, "user"));
-var accounts = sca.reference(editorComp, "accounts");
+(function rootbody() {
/**
- * Set page title.
+ * Setup page layout.
*/
-document.title = config.windowtitle();
+(function layout() {
+
+ document.title = config.windowtitle();
+ $('viewcontainer').className = ui.isMobile()? 'viewcontainer3dm' : 'viewcontainer3d';
+ $('status').className = ui.isMobile()? 'status3dm' : 'status3d';
+
+})();
/**
- * Init div variables.
+ * Initialize service references.
*/
-var bdiv = $('mainbodydiv');
-var mdiv = $('menu');
-var hdiv = $('viewhead');
-var vcontainer = $('viewcontainer');
-vcontainer.className = ui.isMobile()? 'viewcontainer3dm' : 'viewcontainer3d';
-var fdiv = $('viewfoot');
+var editorComp = sca.component("Editor");
+var user = sca.defun(sca.reference(editorComp, "user"));
+var accounts = sca.reference(editorComp, "accounts");
/**
- * The current user name and account entry.
+ * The current user name.
*/
window.username = 'anonymous';
@@ -169,134 +174,95 @@ var storecat = 'top';
var storeidx = 0;
/**
- * Pre-fetch app resources.
+ * Populate cache with app resources.
*/
var appresources = [
['/all-min.js'],
['/ui-min.css'],
['/account/', 9],
- ['/clone/', 3],
- ['/create/', 2],
- ['/delete/', 3],
+ ['/clone/', 4],
+ ['/create/', 3],
+ ['/delete/', 4],
['/graph/', 5],
['/config-min.js'],
['/home/', 0],
- ['/home/home.b64'],
['/page/', 4],
['/public/app.b64'],
['/public/config-min.js'],
- ['/public/grid72.b64'],
- ['/public/iframe-min.html'],
['/public/img.b64'],
+ ['/public/rate.b64'],
+ ['/public/ratings.b64'],
['/public/user.b64'],
- ['/stats/', 2],
+ ['/rate/', 4],
+ ['/search/', 2],
+ ['/info/', 3],
['/store/', 1]
];
/**
- * Show a status message.
+ * Init status message area.
*/
-window.showStatus = function(s, c) {
- //debug('status', s);
- var sdiv = $('status');
- if (isNil(sdiv))
- return s;
- sdiv.innerHTML = '<span class="' + (c? c : 'okstatus') + '">' + s + '</span>';
- sdiv.className = 'status fixed';
- sdiv.style.visibility = 'visible';
+(function initstatus() {
+ if (isNil($('status')))
+ return;
+ $('status').style.display = 'none';
function divtransitionend(e) {
- e.target.style.visibility = 'hidden';
- e.target.className = 'status fixed';
+ e.target.style.display = 'none';
+ e.target.className = ui.isMobile()? 'status3dm' : 'status3d';
+ e.target.error = false;
}
- if (!sdiv.addedTransitionEnd) {
- sdiv.addEventListener('webkitTransitionEnd', divtransitionend, false);
- sdiv.addEventListener('transitionend', divtransitionend, false);
- sdiv.addedTransitionEnd = true;
- }
- sdiv.className = 'statusout3 fixed';
- return s;
-}
+ $('status').addEventListener('webkitTransitionEnd', divtransitionend, false);
+ $('status').addEventListener('transitionend', divtransitionend, false);
+})();
/**
- * Show an error message.
+ * Show a status message.
*/
-window.showError = function(s) {
- //debug('error', s);
- return showStatus(s, 'errorstatus');
-}
+window.showstatus = function(s, c) {
+ //debug('show status', s);
+ if (isNil($('status')) || $('status').error)
+ return s;
+ $('status').innerHTML = '<span class="' + (c? c : 'okstatus') + '">' + s + '</span>';
+ $('status').className = ui.isMobile()? 'status3dm' : 'status3d';
+ $('status').style.display = 'block';
+ $('status').error = c == 'errorstatus';
+ if ($('status').delay)
+ ui.cancelDelay($('status').delay);
+ $('status').delay = ui.delay(function hidestatus() {
+ $('status').className = ui.isMobile()? 'statusout3dm' : 'statusout3d';
+ $('status').error = false;
+ }, 3000);
+ return s;
+};
/**
- * Show the online/offline status.
+ * Show an error message.
*/
-window.showOnlineStatus = function() {
- return navigator.onLine? showStatus('Online') : showError('Offline');
-}
+window.errorstatus = function(s) {
+ //debug('error', s);
+ return showstatus(s, 'errorstatus');
+};
/**
- * Handle application cache events.
+ * Show working status.
*/
-applicationCache.addEventListener('checking', function(e) {
- //debug('appcache checking', e);
- showStatus('Checking');
-}, false);
-applicationCache.addEventListener('error', function(e) {
- //debug('appcache error', e);
- showOnlineStatus();
-}, false);
-applicationCache.addEventListener('noupdate', function(e) {
- //debug('appcache noupdate', e);
- showOnlineStatus();
-}, false);
-applicationCache.addEventListener('downloading', function(e) {
- //debug('appcache downloading', e);
- showStatus('Updating');
-}, false);
-applicationCache.addEventListener('progress', function(e) {
- //debug('appcache progress', e);
- showStatus('Updating');
-}, false);
-applicationCache.addEventListener('updateready', function(e) {
- //debug('appcache updateready', e);
- try {
- applicationCache.swapCache();
- } catch(e) {}
- showOnlineStatus();
- //debug('appcache swapped', e);
-
- // Update offline resources in local storage and reload the page
- map(function(res) {
- showStatus('Updating');
- appcache.remove(res[0]);
- appcache.get(res[0]);
- }, append(appresources, config.appresources()));
- window.location.reload();
-}, false);
-applicationCache.addEventListener('cached', function(e) {
- //debug('appcache cached', e);
- showOnlineStatus();
-
- // Install offline resources in local storage
- map(function(res) {
- showStatus('Installing');
- appcache.remove(res[0]);
- appcache.get(res[0]);
- }, append(appresources, config.appresources()));
-}, false);
+window.workingstatus = function(w, c) {
+ //debug('show working', w);
+ if (isNil($('working')))
+ return w;
+ if (!ui.isMobile())
+ $('working').style.top = ui.pixpos(Math.round(window.clientHeight / 2));
+ $('working').style.display = w? 'block' : 'none';
+ return w;
+};
/**
- * Handle network offline/online events.
+ * Show the online/offline status.
*/
-window.addEventListener('offline', function(e) {
- //debug('going offline');
- showStatus('Offline');
-}, false);
-window.addEventListener('online', function(e) {
- //debug('going online');
- showStatus('Online');
-}, false);
-
-//debug(navigator.onLine? 'online' : 'offline');
+window.onlinestatus = function() {
+ return navigator.onLine? (ui.isMobile()? showstatus('Online') : showstatus('Online')) : errorstatus('Offline');
+};
/**
* Handle view transitions.
@@ -351,32 +317,36 @@ function mkviewdiv(cname) {
* Return the last visited location.
*/
function lastvisited() {
- if (username != lstorage.getItem('ui.lastvisit.user'))
+ if (username != lstorage.getItem('ui.v.user'))
return null;
- return lstorage.getItem('ui.lastvisit.url');
+ return lstorage.getItem('ui.v.url');
}
/**
* Build and show the menu bar.
*/
-function showmenu(mdiv, view, appname) {
- mdiv.innerHTML = ui.menubar(
+function showmenu(view, appname) {
+ $('menu').innerHTML = ui.menubar(
append(mklist(ui.menu('menuhome', 'Home', '/', '_view', view == 'home'),
- ui.menu('menustore', 'Store', '/#view=store&category=' + storecat + '&idx=' + storeidx, '_view', view === 'store')),
+ ui.menu('menustore', 'Store', '/#view=store&category=' + storecat + '&idx=' + storeidx, '_view', view == 'store'),
+ ui.menu('menusearch', 'Search', '/#view=search', '_view', view == 'search')),
(isNil(appname) || appname == 'undefined')?
mklist() :
mklist(
- ui.menu('menustats', 'Stats', '/#view=stats&app=' + appname, '_view', view == 'stats'),
- ui.menu('menupage', 'Page', '/#view=page&app=' + appname, '_view', view == 'page'),
+ ui.menu('menuinfo', 'Info', '/#view=info&app=' + appname, '_view', view == 'info'),
+ ui.menu('menupage', 'Edit', '/#view=page&app=' + appname, '_view', view == 'page')
+ /* TODO disabled for now
+ ,
ui.menu('menulogic', config.logic(), '/#view=graph&app=' + appname, '_view', view == 'graph'),
- ui.menu('menurun', '<span class="greentext" style="font-weight: bold">Run!</span>', '/' + appname + '/', '_blank', false))),
+ ui.menu('menurun', '<span class="greentext" style="font-weight: bold">Run!</span>', '/' + appname + '/', '_blank', false)
+ */
+ )),
(isNil(appname) || appname == 'undefined')? mklist(
- hasauthcookie()? ui.menufunc('menusignout', 'Sign out', 'return logout();', false) : ui.menu('menusignin', 'Sign in', '/login/', '_self', false),
+ ui.menufunc('menusignout', 'Sign out', 'return logout();', false),
ui.menu('menuaccount', 'Account', '/#view=account', '_view', view == 'account')) :
mklist());
- if (fdiv.innerHTML == '')
- fdiv.innerHTML = config.viewfoot();
+ $('viewfoot').innerHTML = config.viewfoot();
}
/**
@@ -390,7 +360,7 @@ function getaccount() {
return false;
var accountentry = car(elementsToValues(atom.readATOMEntry(mklist(doc))));
- username = cadr(assoc("'id", cdr(accountentry)));
+ username = cadr(assoc("'id", accountentry));
return true;
}
@@ -401,8 +371,8 @@ function showview(url) {
//debug('showview', url);
// Save last visited location
- lstorage.setItem('ui.lastvisit.user', username);
- lstorage.setItem('ui.lastvisit.url', url);
+ lstorage.setItem('ui.v.user', username);
+ lstorage.setItem('ui.v.url', url);
// Determine the view to show
var params = ui.fragmentParams(url);
@@ -426,10 +396,11 @@ function showview(url) {
// Show the menu bar
var appname = params['app'];
- showmenu(mdiv, view, appname);
+ showmenu(view, appname);
- // Scroll to the top and hide the address bar
- window.scrollTo(0, 0);
+ // Make sure that the document is visible
+ if (document.body.style.display != 'block')
+ document.body.style.display = 'block';
// Start to unload the front view and create a new view
if (ui.isMobile()) {
@@ -444,21 +415,17 @@ function showview(url) {
var vdiv = mkviewdiv(vtransition + 'viewloading3dm');
var vdoc = appcache.get(uri);
vdiv.innerHTML = vdoc;
- vcontainer.appendChild(vdiv);
+ $('viewcontainer').appendChild(vdiv);
map(ui.evalScript, ui.innerScripts(vdiv));
- // Make sure the top document is visible
- if (document.body.style.visibility != 'visible')
- document.body.style.visibility = 'visible';
-
- setTimeout(function() {
+ ui.async(function mtransitionview() {
// Transition the old view out
if (!isNil(ovdiv))
ovdiv.className = vtransition + 'viewunloaded3dm';
// Transition the new view in
vdiv.className = 'viewloaded3dm';
- }, 100);
+ });
} else {
// Prepare current view for transition out
@@ -470,21 +437,17 @@ function showview(url) {
var vdiv = mkviewdiv('viewloading3d');
var vdoc = appcache.get(uri);
vdiv.innerHTML = vdoc;
- vcontainer.appendChild(vdiv);
+ $('viewcontainer').appendChild(vdiv);
map(ui.evalScript, ui.innerScripts(vdiv));
- // Make sure the top document is visible
- if (document.body.style.visibility != 'visible')
- document.body.style.visibility = 'visible';
-
- setTimeout(function() {
+ ui.async(function transitionview() {
// Transition the new view in
vdiv.className = 'viewloaded3d';
// Transition the old view out
if (!isNil(ovdiv))
ovdiv.parentNode.removeChild(ovdiv);
- }, 100);
+ });
}
// Track the current visible view
@@ -501,12 +464,14 @@ function updatelocation(url) {
// Add url to the history if necessary
if (url != ui.pathandparams(location)) {
- history.pushState(null, null, url);
- //debug('pushstate', history.length);
+ if (history.pushState) {
+ history.pushState(null, null, url);
+ //debug('pushstate', history.length);
+ }
// Update the location hash if necessary
var f = ui.fragment(url);
- if (f != '' && f != location.hash) {
+ if (f != location.hash) {
location.hash = f;
//debug('hash', f);
}
@@ -520,6 +485,10 @@ function updatelocation(url) {
window.onnavigate = function(url) {
//debug('onnavigate', url);
+ // Cleanup installer
+ if ($('installer').innerHTML != '')
+ $('installer').innerHTML = '';
+
// Update the browser window location
updatelocation(url);
@@ -541,12 +510,11 @@ window.onloginredirect = function(e) {
*/
window.logout = function() {
// Clear session cookie and user-specific local storage entries
- clearauthcookie();
lstorage.removeItem('/r/Editor/accounts');
lstorage.removeItem('/r/Editor/dashboards');
- document.location = '/login/';
+ document.location = '/logout/dologout/';
return false;
-}
+};
/**
* Handle history.
@@ -555,10 +523,13 @@ window.addEventListener('popstate', func
//debug('onpopstate', history.length);
var furl = ui.fragment(location);
var url = location.pathname + (furl == ''? '' : '#' + furl);
-
- // Show the current view
if (url == viewurl)
return true;
+
+ // Cleanup element lookups memoized in current document
+ ui.unmemo$();
+
+ // Show the current view
return showview(url);
}, false);
@@ -567,10 +538,13 @@ window.addEventListener('hashchange', fu
//debug('onhashchange');
var furl = ui.fragment(location);
var url = location.pathname + (furl == ''? '' : '#' + furl);
-
- // Show the current view
if (url == viewurl)
return true;
+
+ // Cleanup element lookups memoized in current document
+ ui.unmemo$();
+
+ // Show the current view
return showview(url);
}, false);
@@ -580,18 +554,128 @@ window.addEventListener('hashchange', fu
*/
document.body.onorientationchange = function(e) {
//debug('onorientationchange');
- ui.onorientationchange(e);
-
- // Resize menu and view header
- mdiv.style.width = ui.pixpos(document.documentElement.clientWidth);
- hdiv.style.width = ui.pixpos(document.documentElement.clientWidth);
- return true;
+ return ui.onorientationchange(e);
};
/**
+ * Install the application cache.
+ */
+(function installappcache() {
+ if (ui.isMobile()) {
+ // On mobile devices, trigger usage of an application cache manifest
+ window.onappcachechecking = function(e) {
+ //debug('appcache checking', e);
+ workingstatus(true);
+ showstatus('Checking');
+ };
+ window.onappcacheerror = function(e) {
+ //debug('appcache error', e);
+ onlinestatus();
+ workingstatus(false);
+ };
+ window.onappcachenoupdate = function(e) {
+ //debug('appcache noupdate', e);
+ onlinestatus();
+ workingstatus(false);
+ };
+ window.onappcachedownloading = function(e) {
+ //debug('appcache downloading', e);
+ workingstatus(true);
+ showstatus('Updating');
+ };
+ window.onappcacheprogress = function(e) {
+ //debug('appcache progress', e);
+ workingstatus(true);
+ showstatus('Updating');
+ };
+ window.onappcacheupdateready = function(e) {
+ //debug('appcache updateready', e);
+ try {
+ applicationCache.swapCache();
+ } catch(e) {}
+ onlinestatus();
+ workingstatus(false);
+ //debug('appcache swapped', e);
+
+ // Update offline resources in local storage and reload the page
+ map(function(res) {
+ showstatus('Updating');
+ appcache.remove(res[0]);
+ appcache.get(res[0], 'remote');
+ }, append(appresources, config.appresources()));
+ window.location.reload();
+ };
+ window.onappcachecached = function(e) {
+ //debug('appcache cached', e);
+ onlinestatus();
+ workingstatus(false);
+
+ // Install offline resources in local storage
+ map(function(res) {
+ showstatus('Installing');
+ appcache.remove(res[0]);
+ appcache.get(res[0], 'remote');
+ }, append(appresources, config.appresources()));
+ };
+
+ window.onloadappcache = function() {
+ //debug('appcache iframe loaded');
+ };
+
+ ui.delay(function() {
+ $('installer').innerHTML = '<iframe src="/cache/" class="installer"></iframe>';
+ });
+
+ } else {
+ // On non-mobile devices, check for cache-manifest changes ourselves.
+ workingstatus(true);
+ showstatus('Checking');
+ var lcmf = appcache.get('/cache/cache-manifest.cmf', 'local');
+ var rcmf = appcache.get('/cache/cache-manifest.cmf', 'remote');
+ if (lcmf == rcmf) {
+ onlinestatus();
+ workingstatus(false);
+ return true;
+ }
+
+ //debug('cache-manifest changed, reloading');
+ ui.delay(function() {
+ workingstatus(true);
+ showstatus('Updating');
+ ui.delay(function() {
+ workingstatus(true);
+ showstatus('Updating');
+ map(function(res) {
+ appcache.remove(res[0]);
+ appcache.get(res[0], 'remote');
+ }, append(appresources, config.appresources()));
+ if (!isNil(lcmf)) {
+ //debug('reloading');
+ window.location.reload();
+ }
+ onlinestatus();
+ workingstatus(false);
+ });
+ });
+ }
+})();
+
+/**
+ * Handle network offline/online events.
+ */
+window.addEventListener('offline', function(e) {
+ //debug('going offline');
+ showstatus('Offline');
+}, false);
+window.addEventListener('online', function(e) {
+ //debug('going online');
+ showstatus('Online');
+}, false);
+
+/**
* Initialize the document.
*/
-function onload() {
+window.onload = function() {
//debug('onload', history.length);
ui.onload();
@@ -625,16 +709,15 @@ function onload() {
if (url == viewurl)
return true;
return showview(url);
-}
-
-onload();
+};
})();
-</script>
-<div id="footdiv" class="fsection">
-</div>
+} catch(e) {
+ debug(e.stack);
+ throw e;
+}
+</script>
-</div>
</body>
</html>
Added: tuscany/sca-cpp/trunk/hosting/server/htdocs/info/index.html
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/htdocs/info/index.html?rev=1428193&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/hosting/server/htdocs/info/index.html (added)
+++ tuscany/sca-cpp/trunk/hosting/server/htdocs/info/index.html Thu Jan 3 07:41:53 2013
@@ -0,0 +1,494 @@
+<!DOCTYPE html>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<div id="bodydiv" class="body">
+
+<div id="viewform" class="viewform">
+
+<form id="appForm">
+<table style="width: 100%;">
+<tr><td class="label">URL:</td></tr>
+<tr><td><input type="text" id="appURL" class="readentry" size="30" readonly="readonly" placeholder="App URL" style="width: 300px;"/></td></tr>
+<tr><td class="label">Icon:</td></tr>
+<tr><td><img id="appIcon" style="width: 50px; height: 50px; vertical-align: top;"/><input id="uploadIcon" type="button" class="lightbutton" value="Upload" style="display:none;"/><input id="uploadFile" type="file" accept="image/*" style="display: none;"/><span id="refreshingIcon" class="refreshing" style="display:none;"/></td></tr>
+<tr><td class="label">Author:</td></tr>
+<tr><td><img id="authorPicture" style="width: 50px; height: 50px; vertical-align: middle;"/><input type="text" id="appAuthor" class="readentry" size="30" readonly="readonly" placeholder="Author of the app" style="width: 248px;"/></td></tr>
+<tr><td class="label">Rating:</td></tr>
+<tr><td><span id="appRating" class="ratings"> </span><input id="rateApp" type="button" class="lightbutton" value="Rate this app"/></td></tr>
+<tr><td><input type="text" id="appRatings" class="readentry" size="20" readonly="readonly" placeholder="Number of ratings" style="font-size: 12px;"/></td></tr>
+<tr><td class="label">Updated:</td></tr>
+<tr><td><input type="text" id="appUpdated" class="readentry" size="30" readonly="readonly" placeholder="App update date" style="width: 300px;"/></td></tr>
+<tr><td class="label">Description:</td></tr>
+<tr><td><textarea id="appDescription" class="readentry" cols="40" rows="3" readonly="readonly" placeholder="Short description of the app" style="width: 300px;"></textarea></td></tr>
+</table>
+</form>
+<br/>
+
+</div>
+
+<script type="text/javascript">
+(function infobody() {
+
+/**
+ * Get the app name.
+ */
+var appname = ui.fragmentParams(location)['app'];
+
+/**
+ * Setup page layout.
+ */
+(function layout() {
+ document.title = config.windowtitle() + ' - Info - ' + appname;
+ $('viewhead').innerHTML = '<span id="appname" class="cmenu">' + appname + '</span>' +
+ '<input type="button" class="redbutton plusminus" style="position: absolute; top: 4px; left: 5px;" id="deleteApp" value="-" title="Delete this app" disabled="true"/>' +
+ '<span style="position: absolute; top: 0px; right: 5px;">' +
+ '<input type="button" class="greenbutton" id="runApp" value="Run" title="Run this app"/>' +
+ '<input type="button" class="bluebutton" id="cloneApp" value="'+ config.clone() +'" title="' + config.clone() + ' this app"/>' +
+ '</span>';
+ if (!ui.isMobile())
+ $('viewform').className = 'viewform flatscrollbars';
+ $('appURL').value = window.location.hostname + '/' + appname + '/';
+
+ $('viewform').appendChild(ui.declareCSS(
+ '.ratings { ' +
+ 'background: url(\'' + ui.b64png(appcache.get('/public/ratings.b64')) + '\'); ' +
+ 'vertical-align: middle; width: 50px; height: 14px; display: inline-block; ' +
+ ' }'));
+})();
+
+/**
+ * Set images.
+ */
+(function drawImages() {
+ $('appIcon').src = ui.b64png(appcache.get('/public/app.b64'));
+ $('authorPicture').src = ui.b64png(appcache.get('/public/user.b64'));
+})();
+
+/**
+ * Initialize service references.
+ */
+var editorComp = sca.component("Editor");
+var apps = sca.reference(editorComp, "apps");
+var icons = sca.reference(editorComp, "icons");
+var pictures = sca.reference(editorComp, "pictures");
+var ratings = sca.reference(editorComp, "ratings");
+
+/**
+ * The current app entry, author and saved XML content.
+ */
+var savedappxml = '';
+var author;
+var savediconxml;
+
+/**
+ * Get and display the requested app.
+ */
+(function getapp() {
+ if (isNil(appname))
+ return false;
+ workingstatus(true);
+ showstatus('Loading');
+
+ return apps.get(appname, function(doc) {
+
+ // Stop now if we didn't get the app
+ if (doc == null) {
+ errorstatus('Couldn\'t get the app info');
+ workingstatus(false);
+ return false;
+ }
+
+ var appentry = car(elementsToValues(atom.readATOMEntry(mklist(doc))));
+ author = cadr(assoc("'author", appentry));
+ $('appAuthor').value = author.split('@')[0];
+ var updated = assoc("'updated", appentry);
+ $('appUpdated').value = isNil(updated)? '' : xmldatetime(cadr(updated)).toLocaleDateString();
+ var content = cadr(assoc("'content", appentry));
+ var description = assoc("'description", content);
+ $('appDescription').value = isNil(description) || isNil(cadr(description))? '' : cadr(description);
+ //var ratingy = -20 * (4 - Math.floor(Math.random() * 4));
+ //$('appRating').style.backgroundPosition = '0px ' + ratingy + 'px';
+ //$('appRatings').value = '';
+ savedappxml = car(atom.writeATOMEntry(valuesToElements(mklist(appentry))));
+
+ // Enable author to edit and delete the app
+ if (username == author) {
+ $('appDescription').readOnly = false;
+ $('appDescription').className = 'flatentry';
+ $('uploadIcon').style.display = 'inline';
+ $('deleteApp').disabled = false;
+ $('deleteApp').onclick = function() {
+ return ui.navigate('/#view=delete&app=' + appname, '_view');
+ }
+ onlinestatus();
+ } else {
+ showstatus('Read only');
+ }
+ workingstatus(false);
+ return true;
+ });
+})();
+
+/**
+ * Get and display the author's picture.
+ */
+(function getpic(author) {
+ workingstatus(true);
+ showstatus('Loading');
+
+ return pictures.get(author, function(doc) {
+
+ // Stop now if we didn't get a picture
+ if (doc == null) {
+ errorstatus('Author picture not available');
+ workingstatus(false);
+ return false;
+ }
+
+ var picentry = car(elementsToValues(atom.readATOMEntry(mklist(doc))));
+ var content = assoc("'content", picentry);
+ var picture = assoc("'picture", content);
+ var img = assoc("'image", picture);
+ if (!isNil(img))
+ $('authorPicture').src = cadr(img);
+
+ onlinestatus();
+ workingstatus(false);
+ return true;
+ });
+ return true;
+})();
+
+/**
+ * Get and display the app icon.
+ */
+(function geticon() {
+ if (isNil(appname))
+ return false;
+ workingstatus(true);
+ showstatus('Loading');
+
+ return icons.get(appname, function(doc) {
+ // Stop now if we didn't get an icon
+ if (doc == null) {
+ errorstatus('Icon not available');
+ workingstatus(false);
+ return false;
+ }
+
+ var iconentry = car(elementsToValues(atom.readATOMEntry(mklist(doc))));
+ savediconxml = car(atom.writeATOMEntry(valuesToElements(mklist(iconentry))));
+ var content = assoc("'content", iconentry);
+ var icon = assoc("'icon", content);
+ var img = assoc("'image", icon);
+ if (!isNil(img))
+ $('appIcon').src = cadr(img);
+
+ onlinestatus();
+ workingstatus(false);
+ return true;
+ });
+ return true;
+})();
+
+/**
+ * Refresh icon.
+ */
+var refreshingicon = false;
+function refreshicon() {
+ if (isNil(appname))
+ return false;
+ if (!refreshingicon)
+ return false;
+ $('refreshingIcon').style.display = 'inline-block';
+ return icons.get(appname, function(doc) {
+ if (doc == null) {
+ errorstatus('Icon not available');
+ $('refreshingIcon').style.display = 'none';
+ refreshingicon = false;
+ return false;
+ }
+
+ var iconentry = car(elementsToValues(atom.readATOMEntry(mklist(doc))));
+ var content = assoc("'content", iconentry);
+ var icon = assoc("'icon", content);
+ var token = assoc("'token", icon);
+
+ // Update icon
+ if (isNil(token)) {
+ var entryxml = car(atom.writeATOMEntry(valuesToElements(mklist(iconentry))));
+ savediconxml = entryxml;
+ var img = assoc("'image", icon);
+ if (!isNil(img))
+ $('appIcon').src = cadr(img);
+ $('refreshingIcon').style.display = 'none';
+ refreshingicon = false;
+ return true;
+ }
+
+ // Refresh in 2 secs
+ return ui.delay(refreshicon, 2000);
+ }, 'remote');
+ return true;
+}
+
+/**
+ * Get and display the app ratings.
+ */
+(function getratings() {
+ if (isNil(appname))
+ return false;
+ workingstatus(true);
+ showstatus('Loading');
+
+ return ratings.get(appname, function(doc) {
+ // Stop now if we didn't get an icon
+ if (doc == null) {
+ errorstatus('Ratings not available');
+ workingstatus(false);
+ return false;
+ }
+
+ var ratingsentry = car(elementsToValues(atom.readATOMEntry(mklist(doc))));
+ var aratings = assoc("'ratings", assoc("'content", ratingsentry));
+ var ar = assoc("'rating", aratings);
+ var ar1 = assoc("'rating1", aratings);
+ var ar2 = assoc("'rating2", aratings);
+ var ar3 = assoc("'rating3", aratings);
+ var ar4 = assoc("'rating4", aratings);
+ var rating = isNil(ar)? 0 : Number(cadr(ar));
+ var reviews = (isNil(ar1)? 0 : Number(cadr(ar1))) + (isNil(ar2)? 0 : Number(cadr(ar2))) + (isNil(ar3)? 0 : Number(cadr(ar3))) + (isNil(ar4)? 0 : Number(cadr(ar4)));
+
+ var ratingy = -20 * (4 - Math.floor(rating));
+ $('appRating').style.backgroundPosition = '0px ' + ratingy + 'px';
+ $('appRatings').value = reviews + (reviews > 1? ' ratings' : ' rating');
+
+ onlinestatus();
+ workingstatus(false);
+ return true;
+ });
+ return true;
+})();
+
+/**
+ * Save the current app.
+ */
+function saveapp(entryxml) {
+ workingstatus(true);
+ showstatus('Saving');
+ savedappxml = entryxml;
+ apps.put(appname, savedappxml, function(e) {
+ if (e) {
+ showstatus('Local copy');
+ workingstatus(false);
+ return false;
+ }
+
+ showstatus('Saved');
+ workingstatus(false);
+ return false;
+ });
+ return true;
+}
+
+/**
+ * Save the app icon.
+ */
+function saveicon(entryxml) {
+ workingstatus(true);
+ showstatus('Uploading');
+ savedappxml = entryxml;
+ icons.put(appname, savedappxml, function(e) {
+ if (e) {
+ showstatus('Local copy');
+ workingstatus(false);
+ return false;
+ }
+
+ showstatus('Uploaded');
+ workingstatus(false);
+ return true;
+ });
+ return true;
+}
+
+/**
+ * Handle a change event
+ */
+function onappchange() {
+ if (username != author)
+ return false;
+
+ // Validate user input
+ var description = $('appDescription').value;
+ if (description.length > 120) {
+ errorstatus('Description cannot be longer than 120 characters');
+ return false;
+ }
+
+ // Save the changes
+ var appentry = mklist("'entry", mklist("'title", appname), mklist("'id", appname), mklist("'content", mklist("'info", mklist("'description", description))));
+ var entryxml = car(atom.writeATOMEntry(valuesToElements(mklist(appentry))));
+ if (savedappxml == entryxml)
+ return false;
+ showstatus('Modified');
+ return saveapp(entryxml);
+}
+
+$('appDescription').onchange = onappchange;
+
+/**
+ * Handle a key event.
+ */
+var lastkeyup = null;
+$('appDescription').onkeyup = function() {
+ var t = new Date().getTime();
+ lastkeyup = t;
+ ui.delay(function() {
+ return t == lastkeyup? onappchange() : true;
+ }, 2000);
+};
+
+/**
+ * Handle a form submit event.
+ */
+$('appForm').onsubmit = function() {
+ onappchange();
+ return false;
+};
+
+/**
+ * Handle Clone button event.
+ */
+$('cloneApp').onclick = function() {
+ return ui.navigate('/#view=clone&app=' + appname, '_view');
+};
+
+/**
+ * Handle Run button event.
+ */
+$('runApp').onclick = function() {
+ return ui.navigate('/' + appname + '/', '_blank');
+};
+
+/**
+ * Read and upload icon file.
+ */
+function uploadicon(files) {
+ if (username != author)
+ return false;
+ if (!files || files.length == 0)
+ return false;
+ if (!files[0].type.match('image.*')) {
+ errorstatus('Please select an image');
+ return false;
+ }
+ workingstatus(true);
+ showstatus('Loading');
+
+ // Read the selected file into a 50x50 image
+ return ui.readimage(files[0],
+ function(e) {
+ errorstatus('Couldn\'t read the file');
+ workingstatus(false);
+ },
+ function(p) {
+ showstatus('Loading ' + p + '%');
+ },
+ function(url) {
+ // Update the app icon
+ $('appIcon').src = url;
+ showstatus('Loaded');
+
+ // Now upload it
+ ui.delay(function() {
+ var iconentry = mklist("'entry", mklist("'title", appname), mklist("'id", appname), mklist("'author", username), mklist("'content", mklist("'icon", mklist("'image", url))));
+ var entryxml = car(atom.writeATOMEntry(valuesToElements(mklist(iconentry))));
+ if (savediconxml == entryxml) {
+ onlinestatus();
+ workingstatus(false);
+ return false;
+ }
+ return saveicon(entryxml);
+ });
+ }, 50, 50);
+}
+
+/**
+ * Upload an icon in an email.
+ */
+function emailicon() {
+
+ // Generate and put an icon email upload token
+ workingstatus(true);
+ showstatus('Uploading');
+ var token = uuid4();
+ var iconentry = mklist("'entry", mklist("'title", appname), mklist("'id", appname), mklist("'author", username), mklist("'content", mklist("'icon", mklist("'token", token))));
+ var entryxml = car(atom.writeATOMEntry(valuesToElements(mklist(iconentry))));
+ icons.put(appname, entryxml, function(e) {
+ if (e) {
+ showstatus('Local copy');
+ workingstatus(false);
+ return false;
+ }
+ workingstatus(false);
+
+ // Open the email app
+ var mailto = safeb64encode('i/' + appname + '/' + token);
+ ui.navigate('mailto:' + mailto + '@' + topdomainname(window.location.hostname) + '?subject=Email to upload&body=Paste icon here', '_self');
+
+ // Refresh app icon
+ refreshingicon = true;
+ return ui.delay(refreshicon, 500);
+ }, 'remote');
+}
+
+/**
+ * Handle icon upload events.
+ */
+$('uploadIcon').onclick = function() {
+ if (ui.isMobile())
+ return emailicon();
+ return $('uploadFile').click();
+};
+$('uploadFile').onchange = function(e) {
+ return uploadicon(e.target.files);
+};
+$('appIcon').ondrag = function(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ e.dataTransfer.dropEffect = 'copy';
+};
+$('appIcon').ondrop = function(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ return uploadicon(e.dataTransfer.files);
+};
+
+/**
+ * Handle rate button event.
+ */
+$('rateApp').onclick = function() {
+ return ui.navigate('/#view=rate&app=' + appname, '_view');
+};
+
+})();
+</script>
+
+</div>