HTML cleanup, improve layout on different browsers, iOS and android devices and add robots.txt and some icons. Support execution and preview of components from the edit pages.

git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1086046 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
jsdelfino 2011-03-27 21:58:51 +00:00
commit 093d169f38
39 changed files with 732 additions and 214 deletions

View file

@ -36,6 +36,8 @@ def mkapplink(id):
os.symlink('../../../htdocs/public', 'apps/' + car(id) + '/htdocs/public');
os.symlink('../../../htdocs/data', 'apps/' + car(id) + '/htdocs/data');
os.symlink('../../../htdocs/app/index.html', 'apps/' + car(id) + '/htdocs/index.html');
os.symlink('../../../htdocs/robots.txt', 'apps/' + car(id) + '/htdocs/robots.txt');
os.symlink('../../../htdocs/favicon.ico', 'apps/' + car(id) + '/htdocs/favicon.ico');
os.symlink('../app.html', 'apps/' + car(id) + '/htdocs/app.html');
except:
pass

View file

@ -22,6 +22,10 @@
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
<script type="text/javascript">
document.title = window.location.hostname.split('.')[0];
</script>
<link rel="apple-touch-icon" href="/public/touchicon.png"/>
<link rel="stylesheet" type="text/css" href="/ui.css"/>
<script type="text/javascript" src="/util.js"></script>
<script type="text/javascript" src="/elemutil.js"></script>
@ -33,34 +37,83 @@
<script type="text/javascript" src="/component.js"></script>
</head>
<body class="delayed">
<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;">
<div id="app"></div>
<span id="appFrame"></span>
</div>
<script type="text/javascript">
if (ui.isIE()) $('bodydiv').style.right = -20;
/**
* The main page component.
* Page, every and location components.
*/
var comp = sca.component('page');
var pagecomp = sca.httpclient('page', '/page');
var everycomp = sca.httpclient('every', '/every');
var locationcomp = sca.httpclient('location', '/location');
/**
* Returns the text value of a data element.
* Find a named value in a tree of elements.
*/
function datatext(dv) {
return elementHasValue(dv)? elementValue(dv) : '';
function datavalue(l, id) {
if (isNil(l))
return null;
var e = car(l);
if (id == elementName(e))
return e;
if (!elementHasValue(e)) {
var v = datavalue(elementChildren(e), id);
if (v != null)
return v;
}
return datavalue(cdr(l), id);
}
/**
* Return the value of an input element.
*/
function inputvalue(e) {
if (e.className == 'entry' || e.className == 'password') {
return car(childElements(e)).value;
}
if (e.className == 'button') {
return car(childElements(e)).value;
}
if (e.className == 'checkbox') {
return car(childElements(e)).value;
}
if (e.className == 'list') {
return car(childElements(car(childElements(e)))).value;
}
return null;
};
/**
* Set a data value into a widget.
*/
function setwidgetvalue(e, dv) {
function datatext(dv) {
return elementHasValue(dv)? elementValue(dv) : '';
}
if (e.className == 'h1' || e.className == 'h2' || e.className == 'text' || e.className == 'section') {
car(childElements(e)).innerHTML = datatext(dv);
var t = datatext(dv);
car(childElements(e)).innerHTML = t;
return t;
}
if (e.className == 'button' || e.className == 'entry' || e.className == 'password') {
car(childElements(e)).value = datatext(dv);
if (e.className == 'entry' || e.className == 'password') {
var t = datatext(dv);
car(childElements(e)).defaultValue = t;
return t;
}
if (e.className == 'button') {
var t = datatext(dv);
car(childElements(e)).value = t;
return t;
}
if (e.className == 'checkbox') {
@ -76,16 +129,26 @@ function setwidgetvalue(e, dv) {
ce.innerHTML = t;
return t;
}
if (e.className == 'link') {
var t = datatext(dv);
var ce = car(childElements(car(childElements(e))));
ce.href = t;
ce.innerHTML = t;
if (e.className == 'table') {
var t = ui.datatable(elementChildren(dv));
car(childElements(e)).innerHTML = t;
return t;
}
if (e.className == 'table') {
var t = ui.datatable(mklist(dv));
car(childElements(e)).innerHTML = t;
if (e.className == 'link') {
var t = datatext(dv);
var ce = car(childElements(e));
ce.href = isList(t)? car(t) : t;
car(childElements(ce)).innerHTML = isList(t)? cadr(t) : t;
return t;
}
if (e.className == 'img') {
var t = datatext(dv);
car(childElements(e)).src = t;
return t;
}
if (e.className == 'iframe') {
var t = datatext(dv);
car(childElements(e)).src = t;
return t;
}
return '';
@ -94,56 +157,201 @@ function setwidgetvalue(e, dv) {
/**
* Display data on the app page.
*/
function display(l) {
if (isNil(l))
return false;
var v = car(l);
// For each widget in the app page, look for a data element with the widget id
// then set the data value into the widget
function datavalue(id) {
var dv = namedElementChild("'" + id, v);
return dv;
}
function displaydata(l) {
// Update the widgets values
function updatewidget(e) {
var dv = datavalue(e.id);
var dv = datavalue(l, "'" + e.id);
if (dv == null || isNil(dv))
return e;
setwidgetvalue(e, dv);
return e;
}
var e = map(updatewidget, filter(function(e) { return !isNil(e.id); }, nodeList(ui.elementByID($('app'), 'page').childNodes)));
// Make the page visible
ui.showbody();
map(updatewidget, filter(function(e) { return !isNil(e.id); }, nodeList(ui.elementByID($('app'), 'page').childNodes)));
return true;
}
/**
* Get the contents of the main page component.
* Display data from a document on the app page.
*/
function getdata() {
$('app').innerHTML = $('appFrame').contentDocument.body.innerHTML;
function displaydoc(doc) {
if (isNil(doc))
return true;
var doc = comp.get('', function(doc) {
if (json.isJSON(mklist(doc)))
return displaydata(json.readJSON(mklist(doc)));
if (json.isJSON(mklist(doc)))
return display(json.readJSON(mklist(doc)));
if (atom.isATOMEntry(mklist(doc)))
return displaydata(atom.readATOMEntry(mklist(doc)));
if (atom.isATOMEntry(mklist(doc)))
return display(atom.readATOMEntry(mklist(doc)));
if (atom.isATOMFeed(mklist(doc)))
return displaydata(atom.readATOMFeed(mklist(doc)));
if (atom.isATOMFeed(mklist(doc)))
return display(atom.readATOMFeed(mklist(doc)));
return displaydata(doc);
}
return display(doc);
/**
* Bind a handler to a widget.
*/
function bindwidgethandler(e) {
if (e.className == 'button') {
var b = car(childElements(e));
b.onclick = function() { return buttonClickHandler(e.id); };
return e;
}
if (e.className == 'button' || e.className == 'entry' || e.className == 'password' || e.className == 'checkbox') {
car(childElements(e)).name = e.id;
return e;
}
if (e.className == 'list') {
var ce = car(childElements(car(childElements(e))));
ce.name = e.id;
return e;
}
return 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>';
return e;
}
return e;
}
/**
* Get app data from the main app page component.
*/
function getpagedata() {
// Display component data on the page
function displaypage(doc) {
if (!isNil(doc))
displaydoc(doc);
// Reveal the page
ui.showbody();
return true;
}
// Eval a component init script
function evalcompinit(doc) {
if (isNil(doc))
return true;
var js = car(json.readJSON(mklist(doc)));
if (!elementHasValue(js))
return true;
eval(elementValue(js));
return true;
}
// Initial setup of a widget
function setupwidget(e) {
fixupwidget(e);
bindwidgethandler(e);
}
// Get the component app data
var doc = pagecomp.get(window.location.search, function(doc) {
$('app').innerHTML = $('appFrame').contentDocument.body.innerHTML;
// Initial setup of the widgets
map(setupwidget, filter(function(e) { return !isNil(e.id); }, nodeList(ui.elementByID($('app'), 'page').childNodes)));
// Display data on the page
displaypage(doc);
// Get and eval the optional timer and location watch setup scripts
everycomp.get('setup', evalcompinit);
locationcomp.get('setup', evalcompinit);
return true;
});
return true;
}
/**
* Get app data from a component.
*/
function getcompdata(comp, qs) {
var doc = comp.get(qs, function(doc) {
return displaydoc(doc);
});
return true;
}
/**
* Build a query string from the values of the page's input fields.
*/
function compquery() {
function queryarg(e) {
return e.id + '=' + inputvalue(e);
}
var args = map(queryarg, filter(function(e) { return !isNil(e.id) && !isNil(inputvalue(e)); }, nodeList(ui.elementByID($('app'), 'page').childNodes)));
// Append current location properties if known
if (!isNil(geoposition)) {
var g = geoposition;
args = append(args, mklist('latitude=' + g.coords.latitude, 'longitude=' + g.coords.longitude, 'altitude=' + g.coords.altitude,
'accuracy=' + g.coords.accuracy, 'altitudeAccuracy=' + g.coords.altitudeAccuracy, 'heading=' + g.coords.heading,
'speed=' + g.coords.speed));
}
return '?' + args.join('&');
}
/**
* Handle a button click event.
*/
function buttonClickHandler(id) {
return getcompdata(sca.component(id), compquery());
}
/**
* Handle a timer interval event.
*/
function intervalHandler() {
return getcompdata(everycomp, compquery());
}
/**
* Setup an interval timer.
*/
function setupIntervalHandler(sec) {
return setInterval(intervalHandler, sec);
}
/**
* Handle a location watch event.
*/
var geoposition;
function locationHandler(pos) {
geoposition = pos;
return getcompdata(locationcomp, compquery());
}
function locationErrorHandler(e) {
return true;
}
/**
* Setup a location watch handler.
*/
function setupLocationHandler() {
navigator.geolocation.getCurrentPosition(locationHandler, locationErrorHandler);
navigator.geolocation.watchPosition(locationHandler, locationErrorHandler);
return true;
}
// Load the app frame
$('app').innerHTML = '<iframe id="appFrame" class="widgetFrame" src="app.html" onload="getdata()"></iframe>';
$('app').innerHTML = '<iframe id="appFrame" class="widgetFrame" src="app.html" onload="getpagedata()"></iframe>';
</script>
</body>

View file

@ -27,7 +27,7 @@
<script type="text/javascript" src="/ui.js"></script>
<script type="text/javascript" src="/component.js"></script>
</head>
<body>
<body class="delayed">
<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;">
@ -46,7 +46,7 @@
<table style="width: 100%;">
<tr><td><b>App Name:</b></td></tr>
<tr><td><input type="text" id="appName" size="10"/></td></tr>
<tr><td><input type="text" id="appName" size="10"/>&nbsp;<span id="appDomain"></span></td></tr>
<tr><tr><td><b>App Title:</b></td></tr>
<tr><td><input type="text" id="appTitle" size="80"/></td></tr>
<tr><tr><td><b>Category:</b></td></tr>
@ -71,34 +71,59 @@ if (ui.isIE()) $('bodydiv').style.right = -20;
var editWidget = sca.component("EditWidget");
var dashboard = sca.reference(editWidget, "dashboard");
/**
* Return the link to an app.
*/
function applink(appname) {
var protocol = window.location.protocol;
var host = window.location.hostname;
var port = ':' + window.location.port;
if (port == ':80' || port == ':443' || port == ':')
port = '';
var link = protocol + '//' + appname + '.' + host + port + '/';
return link;
}
/**
* Get and display list of apps.
*/
function getapps(sync) {
function display(doc) {
var apps = '<table style="width: 100%;">';
apps += '<tr><th class="thl thr" style="width: 225px; min-width: 225px; padding-top: 4px; padding-right: 4px;">App</th>' +
apps += '<tr><th class="thl thr" style="width: 20px; padding-top: 4px; padding-right: 4px;">App</th>' +
'<th class="thr thl" style="width: 20px;">Domain</th>' +
'<th class="thr thl">Category</th>' +
'<th class="thr thl" style="width: 100%;">Title</th>' +
'<th class="thl thr" style="width: 30px;">Sharing</th></tr>';
'<th class="thr thl">Updated</th>' +
'<th class="thl thr">Sharing</th></tr>';
var feed = car(elementsToValues(atom.readATOMFeed(mklist(doc))));
var entries = cadr(assoc("'entry", cdr(feed)));
for (var i = 0; i < length(entries); i++) {
var entry = entries[i];
title = cadr(assoc("'title", entry))
name = cadr(assoc("'id", entry))
hreflink = '<a href=\"' + '/graph/?app=' + name + '\" target=\"_parent\">';
sharing = 'Shared with everybody';
var title = cadr(assoc("'title", entry))
var name = cadr(assoc("'id", entry))
var editlink = '<a href=\"' + '/graph/?app=' + name + '\" target=\"_parent\">';
var domainlink = '<a href=\"' + applink(name) + '\" target=\"_' + name + '\">' + name + '.' + window.location.hostname + '</a>';
var category = 'coolapps';
var updated = 'Feb 4, 2011';
var sharing = 'Public';
apps += '<tr class="trb"><td>';
apps += hreflink + '<img src="/public/app.png" style="width: 50px; height: 50px; margin-right: 10px; vertical-align: middle;"></img>' + '</a>';
apps += '&nbsp;' + hreflink + name + '</a></td>';
apps += editlink + '<img src="/public/app.png" style="width: 50px; height: 50px; margin-right: 10px; vertical-align: middle;"></img>' + '</a>';
apps += '&nbsp;' + editlink + name + '</a></td>';
apps += '<td>' + domainlink + '</td>';
apps += '<td>' + category + '</td>';
apps += '<td class="tdw">' + title + '</td>';
apps += '<td>' + updated + '</td>';
apps += '<td>' + sharing + '</td>';
apps += '</tr>';
}
apps += '</table>';
$('apps').innerHTML = apps;
// Show the page
ui.showbody();
}
if (sync) {
@ -123,6 +148,7 @@ var defdesc = 'Enter a short description of your app here';
*/
$('createAppButton').onclick = function() {
$('appName').value = '';
$('appDomain').innerHTML = '.' + window.location.hostname;
$('appTitle').value = deftitle;
$('appCategory').value = defcategory;
$('appDescription').value = defdesc;

View file

@ -22,6 +22,7 @@
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
<link rel="apple-touch-icon" href="/public/touchicon.png"/>
<link rel="stylesheet" type="text/css" href="/ui.css"/>
<script type="text/javascript" src="/util.js"></script>
<script type="text/javascript" src="/ui.js"></script>
@ -29,24 +30,25 @@
<body class="delayed">
<div id="menu"></div>
<script type="text/javascript">
// Load the menu bar
ui.loadwidget('menu', '/menu.html', ui.showbody);
</script>
<h1>App Edit</h1>
<h1 id="h1"></h1>
<br/>
<div id="dashboard"></div>
<script type="text/javascript">
// Load the menu bar
ui.loadwidget('menu', '/menu.html', ui.showbody);
$('h1').innerHTML = domaintitle(window.location.hostname);
// Load the dashboard
$('dashboard').innerHTML =
'<iframe id="dashboardFrame" style="height: 5000px; width: 100%; border: 0px;" scrolling="no" frameborder="0" src="dashboard.html"></iframe>';
ui.showbody();
</script>
</body>
</html>

View file

@ -17,11 +17,16 @@
* under the License.
-->
<html>
<head>
<title>Results</title>
<head>
<title>View</title>
<script type="text/javascript">
var cn = window.location.search.substring(1).split('=')[1];
document.title = 'View - ' + window.location.hostname.split('.')[0] + '/' + cn;
</script>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
<link rel="apple-touch-icon" href="/public/touchicon.png"/>
<link rel="stylesheet" type="text/css" href="/ui.css">
<script type="text/javascript" src="/util.js"></script>
<script type="text/javascript" src="/elemutil.js"></script>
@ -32,7 +37,7 @@
<script type="text/javascript" src="/ui.js"></script>
<script type="text/javascript" src="/component.js"></script>
</head>
<body>
<body class="delayed">
<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;">
@ -52,9 +57,18 @@ var comp = sca.component(cname);
*/
function display(e) {
$('bodydiv').innerHTML = e;
ui.showbody();
return true;
}
/**
* Convert data to an HTML table.
*/
function datatable(e) {
return ui.datatable(e);
}
/**
* Wrap a document in an HTML table.
*/
@ -70,15 +84,15 @@ function getdata() {
comp.get('', function(doc) {
if (json.isJSON(mklist(doc)))
return display(ui.datatable(json.readJSON(mklist(doc))));
return display(datatable(json.readJSON(mklist(doc))));
if (atom.isATOMEntry(mklist(doc)))
return display(ui.datatable(atom.readATOMEntry(mklist(doc))));
return display(datatable(atom.readATOMEntry(mklist(doc))));
if (atom.isATOMFeed(mklist(doc)))
return display(ui.datatable(atom.readATOMFeed(mklist(doc))));
return display(datatable(atom.readATOMFeed(mklist(doc))));
return display(mkdoctable(doc));
return display(mkdoctable('<iframe style="width: 100%; height: 5000px;" scrolling="no" frameborder="0" src="' + comp.uri + '"/>'));
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -28,7 +28,7 @@
<script type="text/javascript" src="/component.js"></script>
<script type="text/javascript" src="graph.js"></script>
</head>
<body>
<body class="delayed">
<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;">
@ -39,8 +39,9 @@
<th class="thr" style="padding-left: 4px; padding-top: 0px; padding-bottom: 0px;">
<input id="compName" type="text" value="component name" title="Component name" style="position: relative; width: 200px;"/>
<input id="propValue" type="text" value="property value" title="Component property value" style="position: relative; width: 300px;"/>
<input type="button" id="autoplayButton" title="Turn autoplay on/off" style="font-weight: bold;" Value="Autoplay is on"/>
<span id="compValue" style="position: relative; font-weight: normal;"></span><br/>
<input type="button" id="autoplayButton" title="Turn preview on/off" style="font-weight: bold;" Value="Preview is on"/>
<span id="compValue" style="position: relative; font-weight: normal;"></span>
<span id="compDebug" style="position: relative; font-weight: normal;"></span>
</th>
<th class="thl thr" style="padding-top: 0px; padding-bottom: 0px; padding-right: 0px; text-align: right;">
@ -114,6 +115,9 @@ function getapp(name, g) {
// Track the saved composite XML
savedcomposxml = car(writeXML(composite, false));
// Show the page
ui.showbody();
});
}
@ -202,6 +206,21 @@ function compvaluelink(appname, cname) {
return link;
}
/**
* Return the link to a component raw data.
*/
function compdebuglink(appname, cname) {
if (cname == '' || isNil(cname))
return '';
var protocol = window.location.protocol;
var host = window.location.hostname;
var port = ':' + window.location.port;
if (port == ':80' || port == ':443' || port == ':')
port = '';
var link = protocol + '//' + appname + '.' + host + port + '/components/' + cname;
return link;
}
/**
* Track whether we're always showing the result data of the selected component.
*/
@ -228,13 +247,30 @@ function oncompselect(appname, cname) {
return true;
compname = cname;
var link = compvaluelink(appname, cname);
$('compValue').innerHTML = link != ''? '<a href="' + link + '" target="_blank">' + 'Results' + '</a>' : '';
$('compValue').innerHTML = link != ''? '<input type="button" id="playButton" title="View the component value" style="font-weight: bold;" value="View" onclick="playcomp()"/>' : '';
$('compDebug').innerHTML = link != ''? '<input type="button" id="debugButton" title="View the component raw data" style="font-weight: bold;" value="URL" onclick="debugcomp()"/>' : '';
if (autoplay)
return showData(cname);
return true;
}
/**
* Play the current component.
*/
function playcomp() {
var link = compvaluelink(appname, compname);
return window.open(link, '_' + appname + '_' + compname);
}
/**
* Debug the current component.
*/
function debugcomp() {
var link = compdebuglink(appname, compname);
return window.open(link, '_' + appname + '_' + compname);
}
/**
* Handle autoplay on/off click event.
*/
@ -242,15 +278,18 @@ $('autoplayButton').onclick = function(e) {
if (autoplay) {
autoplay = false;
showData('');
$('autoplayButton').value = 'Autoplay is off';
$('autoplayButton').value = 'Autorun is off';
return true;
}
autoplay = true;
showData(compname);
$('autoplayButton').value = 'Autoplay is on';
$('autoplayButton').value = 'Autorun is on';
return true;
};
// Init the play app button
// Create editor graph area
var g = graph.mkgraph(graph.mkpath().move(0,40), $('compName'), $('propValue'));
var bg = graph.mkgroup(graph.mkpath());
@ -261,16 +300,16 @@ var spalette = 'event';
var pos = graph.mkpath();
installpalette('event', pos.rmove(0,0), g, bg, spalette, gpalettes);
installpalette('value', pos.rmove(0,40), g, bg, spalette, gpalettes);
installpalette('url', pos.rmove(0, 40), g, bg, spalette, gpalettes);
installpalette('list', pos.rmove(0, 40), g, bg, spalette, gpalettes);
installpalette('transform', pos.rmove(0, 40), g, bg, spalette, gpalettes);
installpalette('text', pos.rmove(0, 40), g, bg, spalette, gpalettes);
installpalette('logic', pos.rmove(0, 40), g, bg, spalette, gpalettes);
installpalette('math', pos.rmove(0, 40), g, bg, spalette, gpalettes);
installpalette('http', pos.rmove(0, 40), g, bg, spalette, gpalettes);
installpalette('talk', pos.rmove(0, 40), g, bg, spalette, gpalettes);
installpalette('social', pos.rmove(0, 40), g, bg, spalette, gpalettes);
installpalette('search', pos.rmove(0, 40), g, bg, spalette, gpalettes);
installpalette('sensor', pos.rmove(0, 40), g, bg, spalette, gpalettes);
installpalette('logic', pos.rmove(0, 40), g, bg, spalette, gpalettes);
installpalette('math', pos.rmove(0, 40), g, bg, spalette, gpalettes);
installpalette('python', pos.rmove(0, 40), g, bg, spalette, gpalettes);
// Get and display the current app
getapp(appname, g);

View file

@ -408,7 +408,7 @@ if (ui.isIE()) {
graph.comptitlewidth = function(comp) {
var t = graph.title(comp);
graph.comptitlewidthdiv.innerHTML = t;
var twidth = graph.comptitlewidthdiv.offsetWidth + 4;
var twidth = graph.comptitlewidthdiv.offsetWidth + 2;
graph.comptitlewidthdiv.innerHTML = '';
return twidth;
};
@ -419,7 +419,7 @@ if (ui.isIE()) {
graph.proptitle = function(comp) {
var tsvcs = graph.tsvcs(comp);
var lsvcs = graph.lsvcs(comp);
var pos = graph.mkpath().move(isNil(lsvcs)? tabsz : (tabsz * 5), isNil(tsvcs)? 15 + tabsz : 15 + (tabsz * 5));
var pos = graph.mkpath().move(graph.comptitlewidth(comp) + 7 + (isNil(lsvcs)? tabsz : (tabsz * 5)), isNil(tsvcs)? tabsz : (tabsz * 5));
return graph.mktitle(graph.property(comp), true, pos);
};
@ -429,7 +429,7 @@ if (ui.isIE()) {
graph.proptitlewidth = function(comp) {
var t = graph.property(comp);
graph.proptitlewidthdiv.innerHTML = t;
var twidth = graph.proptitlewidthdiv.offsetWidth + 4;
var twidth = graph.proptitlewidthdiv.offsetWidth + 2;
graph.proptitlewidthdiv.innerHTML = '';
return twidth;
};
@ -902,7 +902,7 @@ if (ui.isIE()) {
graph.comptitlewidth = function(comp) {
var title = graph.comptitle(comp);
graph.titlewidthsvg.appendChild(title);
var width = title.getBBox().width + 4;
var width = title.getBBox().width + 2;
graph.titlewidthsvg.removeChild(title);
return width;
};
@ -930,7 +930,7 @@ if (ui.isIE()) {
*/
graph.proptitle = function(comp) {
var title = graph.mktitle(graph.property(comp), true);
title.setAttribute('y', 30);
title.setAttribute('x', graph.comptitlewidth(comp) + 7);
return title;
};
@ -940,7 +940,7 @@ if (ui.isIE()) {
graph.proptitlewidth = function(comp) {
var title = graph.proptitle(comp);
graph.titlewidthsvg.appendChild(title);
var width = title.getBBox().width + 4;
var width = title.getBBox().width + 2;
graph.titlewidthsvg.removeChild(title);
return width;
};
@ -1085,7 +1085,9 @@ graph.title = function(e) {
return '>'
if (t == 'lt')
return '<';
return t;
if (t.indexOf('{') == -1)
return t;
return t.replace('{compname}', scdl.name(e));
}
return scdl.name(e);
};
@ -1236,8 +1238,6 @@ graph.compheight = function(comp, cassoc) {
var height = Math.max(lsvcsh, rrefsh);
if (!isNil(graph.brefs(comp)))
height = Math.max(height, (tabsz * 10) + (tabsz * 4) + (tabsz * 2));
if (graph.property(comp) != '')
height = Math.max(40, height);
return height;
});
};
@ -1288,7 +1288,7 @@ graph.rrefswidth = function(refs, cassoc) {
*/
graph.compwidth = function(comp, cassoc) {
return memo(comp, 'width', function() {
var twidth = Math.max(graph.comptitlewidth(comp), graph.proptitlewidth(comp)) + (tabsz * 8);
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);

View file

@ -18,10 +18,11 @@
-->
<html>
<head>
<title>App Composition Editor</title>
<title>Composition</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
<link rel="apple-touch-icon" href="/public/touchicon.png"/>
<link rel="stylesheet" type="text/css" href="/ui.css"/>
<script type="text/javascript" src="/util.js"></script>
<script type="text/javascript" src="/ui.js"></script>
@ -29,6 +30,11 @@
<body class="delayed">
<div id="menu"></div>
<h1><span id="h1"></span> <span id="appNameHeader" style="font-weight: normal;"></span></h1>
<br/>
<div id="graph"></div>
<script type="text/javascript">
// Get the app name
@ -36,14 +42,10 @@ var appname = ui.queryParams()['app'];
// Load the menu bar
ui.loadwidget('menu', '/menu.html?app=' + appname, ui.showbody);
</script>
<h1>App Edit <span id="appNameHeader" style="font-weight: normal;"></span></h1>
<br/>
<div id="graph"></div>
<script type="text/javascript">
$('h1').innerHTML = domaintitle(window.location.hostname);
document.title = 'Composition - ' + appname;
$('appNameHeader').innerHTML = ' - ' + appname;
/**
* Display the editor for an app.
@ -58,11 +60,11 @@ function editapp(name) {
}
// Display the editor for the current app
document.title = 'Composition - ' + appname;
$('appNameHeader').innerHTML = ' - ' + appname;
editapp(appname);
ui.showbody();
</script>
</body>
</html>

View file

@ -18,33 +18,39 @@
-->
<html>
<head>
<title>App Edit</title>
<title>Home</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
<link rel="apple-touch-icon" href="/public/touchicon.png"/>
<link rel="stylesheet" type="text/css" href="/ui.css"/>
<script type="text/javascript" src="/util.js"></script>
<script type="text/javascript">
document.title = domaintitle(window.location.hostname);
</script>
<script type="text/javascript" src="/ui.js"></script>
</head>
<body class="delayed">
<div id="menu"></div>
<script type="text/javascript">
// Load the menu bar
ui.loadwidget('menu', '/menu.html', ui.showbody);
</script>
<h1>App Edit</h1>
<h1 id="h1"></h1>
<br/>
<div id="main"></div>
<script type="text/javascript">
// Load the menu bar
ui.loadwidget('menu', '/menu.html', ui.showbody);
$('h1').innerHTML = domaintitle(window.location.hostname);
// Load the main page
ui.loadiframe('main', 'main.html');
ui.showbody();
</script>
</body>
</html>

View file

@ -19,9 +19,11 @@
<html>
<head>
<title>Sign in</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
<link rel="apple-touch-icon" href="/public/touchicon.png"/>
<link rel="stylesheet" type="text/css" href="/ui.css"/>
<script type="text/javascript" src="/util.js"></script>
<script type="text/javascript" src="/ui.js"></script>
@ -69,7 +71,8 @@ if (typeof(oauthReferrer()) == 'undefined') {
}
function submitFormSignin() {
document.cookie = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';path=/;secure=TRUE';
var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE';
document.cookie = reset;
document.formSignin.httpd_location.value = oauthReferrer();
document.formSignin.submit();
}

View file

@ -19,9 +19,11 @@
<html>
<head>
<title>Sign out</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
<link rel="apple-touch-icon" href="/public/touchicon.png"/>
<link rel="stylesheet" type="text/css" href="/ui.css"/>
<script type="text/javascript" src="/util.js"></script>
<script type="text/javascript" src="/ui.js"></script>
@ -36,7 +38,8 @@
<script type="text/javascript">
function submitSignout() {
document.cookie = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';path=/;secure=TRUE';
var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE';
document.cookie = reset;
document.signout.submit();
return true;
}

View file

@ -22,14 +22,14 @@
<script type="text/javascript" src="/util.js"></script>
<script type="text/javascript" src="/ui.js"></script>
</head>
<body>
<body class="delayed">
<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;">
<div style="margin-left: auto; margin-right: auto; text-align: center;">
<br/><br/><br/>
<a href="dash" target="_parent"><img src="home.png" style="width: 426px; height: 145px;"></img></a>
<a href="dash" target="_parent"><img src="home.png" style="width: 426px; height: 145px;"/></a>
<br/><br/>
@ -38,12 +38,17 @@
<br/><br/><br/>
<div>This module implements a simple App store to help you create and share Tuscany apps.</div>
<div>The user interface is minimalistic, by design.</div>
<br/>
<div>Works with Safari, Chrome and Firefox. Doesn't work with IE.</div>
</div>
</div>
<script type="text/javascript">
if (ui.isIE()) $('bodydiv').style.right = -20;
ui.showbody();
</script>
</body>

View file

@ -51,12 +51,25 @@ function appname() {
return ui.queryParams()['app'];
}
/**
* Return the link to an app.
*/
function applink(appname) {
var protocol = window.location.protocol;
var host = window.location.hostname;
var port = ':' + window.location.port;
if (port == ':80' || port == ':443' || port == ':')
port = '';
var link = protocol + '//' + appname + '.' + host + port + '/';
return link;
}
// Display the menu bar
var mdiv = $('menu');
var name = appname();
mdiv.innerHTML = ui.menubar(
append(mklist(ui.menu('Home', '/'), ui.menu('Store', '/store'), ui.menu('Dashboard', '/dash')),
(isNil(name) || name == 'undefined')? mklist() : mklist(ui.menu('Composition', '/graph/?app=' + name), ui.menu('Page', '/page/?app=' + name), ui.menu('Settings', '/props/?app=' + name))),
(isNil(name) || name == 'undefined')? mklist() : mklist(ui.menu('Composition', '/graph/?app=' + name), ui.menu('Page', '/page/?app=' + name), ui.menu('Settings', '/props/?app=' + name), ui.menu(name + '.' + window.location.hostname, applink(name), '_' + name))),
mklist(userMenu(), ui.menu('Account', '/account'), ui.menu('Sign out', '/logout')));
</script>

View file

@ -18,10 +18,11 @@
-->
<html>
<head>
<title>App Page Editor</title>
<title>Page</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
<link rel="apple-touch-icon" href="/public/touchicon.png"/>
<link rel="stylesheet" type="text/css" href="/ui.css"/>
<script type="text/javascript" src="/util.js"></script>
<script type="text/javascript" src="/ui.js"></script>
@ -29,6 +30,11 @@
<body class="delayed">
<div id="menu"></div>
<h1><span id="h1"></span> <span id="appNameHeader" style="font-weight: normal;"></span></h1>
<br/>
<div id="page"></div>
<script type="text/javascript">
// Get the app name
@ -36,14 +42,11 @@ var appname = ui.queryParams()['app'];
// Load the menu bar
ui.loadwidget('menu', '/menu.html?app=' + appname, ui.showbody);
</script>
<h1>App Edit <span id="appNameHeader" style="font-weight: normal;"></span></h1>
<br/>
<div id="page"></div>
<script type="text/javascript">
// Display the editor for the current app
document.title = 'Page - ' + appname;
$('h1').innerHTML = domaintitle(window.location.hostname);
$('appNameHeader').innerHTML = ' - ' + appname;
/**
* Display the page editor for an app.
@ -57,11 +60,9 @@ function editapp(name) {
'"></iframe>';
}
// Display the editor for the current app
document.title = 'Page - ' + appname;
$('appNameHeader').innerHTML = ' - ' + appname;
editapp(appname);
ui.showbody();
</script>
</body>
</html>

View file

@ -28,7 +28,7 @@
<script type="text/javascript" src="/component.js"></script>
<script type="text/javascript" src="page.js"></script>
</head>
<body>
<body class="delayed">
<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;">
@ -52,19 +52,20 @@
<div id="page" style="position: absolute; top: 40px; left: 0px; width: 5000px; height: 5000px;">
<span class="h1" id="palette:h1" style="position: absolute; left: 0px; top: 0px;"><h1>Header1</h1></span>
<span class="h2" id="palette:h2" style="position: absolute; left: 0px; top: 40px;"><h2>Header2</h2></span>
<span class="section" id="palette:section" style="position: absolute; left: 0px; top: 80px;"><span class="section">section</span></span>
<span class="button" id="palette:button" style="position: absolute; left: 0px; top: 120px;"><input type="button" value="button"/></span>
<span class="entry" id="palette:entry" style="position: absolute; left: 0px; top: 160px;"><input type="text" value="field" size="5"/></span>
<span class="password" id="palette:password" style="position: absolute; left: 0px; top: 200px;"><input type="password" value="password" size="5"/></span>
<span class="checkbox" id="palette:checkbox" style="position: absolute; left: 0px; top: 240px;"><input type="checkbox" value="checkbox"/><span>checkbox</span></span>
<span class="list" id="palette:list" style="position: absolute; left: 0px; top: 280px;"><select><option value="list">list</option></select></span>
<span class="table" id="palette:table" style="position: absolute; left: 0px; top: 320px;">
<table class="datatable"><tr><td class="datatdl">name</td><td class="datatdr">value</td></tr><tr><td class="datatdl">name</td><td class="datatdr">value</td></tr></table>
<span class="h2" id="palette:h2" style="position: absolute; left: 0px; top: 35px;"><h2>Header2</h2></span>
<span class="section" id="palette:section" style="position: absolute; left: 0px; top: 70px;"><span class="section">section</span></span>
<span class="button" id="palette:button" style="position: absolute; left: 0px; top: 100px;"><input type="button" value="button"/></span>
<span class="entry" id="palette:entry" style="position: absolute; left: 0px; top: 130px;"><input type="text" value="field" size="10"/></span>
<span class="password" id="palette:password" style="position: absolute; left: 0px; top: 160px;"><input type="password" value="password" size="10"/></span>
<span class="checkbox" id="palette:checkbox" style="position: absolute; left: 0px; top: 190px;"><input type="checkbox" value="checkbox"/><span>checkbox</span></span>
<span class="list" id="palette:list" style="position: absolute; left: 0px; top: 220px;"><select><option value="list">list</option></select></span>
<span class="table" id="palette:table" style="position: absolute; left: 0px; top: 250px;">
<table class="datatable"><tr><td class="datatdl">table</td><td class="datatdr">...</td></tr><tr><td class="datatdl">...</td><td class="datatdr">...</td></tr></table>
</span>
<span class="link" id="palette:link" style="position: absolute; left: 0px; top: 380px;"><a href="/"><span>link</span></a></span>
<span class="text" id="palette:text" style="position: absolute; left: 0px; top: 420px;"><span>text</span></span>
<span class="img" id="palette:img" style="position: absolute; left: 0px; top: 460px;"><img src=""/></span>
<span class="link" id="palette:link" style="position: absolute; left: 0px; top: 300px;"><a href="/"><span>link</span></a></span>
<span class="text" id="palette:text" style="position: absolute; left: 0px; top: 330px;"><span>text</span></span>
<span class="iframe" id="palette:iframe" style="position: absolute; left: 0px; top: 360px;"><a href="/public/iframe.html"><span class="fakeframe"><span>frame ...</span></span></a></span>
<span class="img" id="palette:img" style="position: absolute; left: 0px; top: 390px;"><img src="/public/img.png"/></span>
</div>
@ -129,6 +130,9 @@ function getpage(name, edit) {
}, nodeList(buffer.childNodes[0].childNodes));
savedpagexhtml = pagexhtml();
// Show the page
ui.showbody();
});
}

View file

@ -337,12 +337,23 @@ if (ui.isIE()) {
page.text = function(e) {
if (e.className == 'h1' || e.className == 'h2' || e.className == 'text' || e.className == 'section')
return car(childElements(e)).innerHTML;
if (e.className == 'button' || e.className == 'entry' || e.className == 'password' || e.className == 'checkbox')
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 == 'list')
return car(childElements(car(childElements(e)))).value;
if (e.className == 'link')
return car(childElements(car(childElements(e)))).innerHTML;
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 == 'table')
return '';
return '';
@ -357,7 +368,7 @@ page.settext = function(e, t) {
return t;
}
if (e.className == 'button' || e.className == 'entry' || e.className == 'password') {
car(childElements(e)).value = t;
car(childElements(e)).defaultValue = t;
return t;
}
if (e.className == 'checkbox') {
@ -371,15 +382,24 @@ page.settext = function(e, t) {
ce.innerHTML = t;
return t;
}
if (e.className == 'link') {
var ce = car(childElements(car(childElements(e))));
ce.href = t;
ce.innerHTML = t;
return t;
}
if (e.className == 'table') {
return '';
}
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);
return t;
}
if (e.className == 'img') {
car(childElements(e)).src = t;
return t;
}
if (e.className == 'iframe') {
car(childElements(e)).href = t;
return t;
}
return '';
};

View file

@ -18,10 +18,11 @@
-->
<html>
<head>
<title>App Settings</title>
<title>Settings</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
<link rel="apple-touch-icon" href="/public/touchicon.png"/>
<link rel="stylesheet" type="text/css" href="/ui.css"/>
<script type="text/javascript" src="/util.js"></script>
<script type="text/javascript" src="/ui.js"></script>
@ -29,6 +30,11 @@
<body class="delayed">
<div id="menu"></div>
<h1><span id="h1"></span> <span id="appNameHeader" style="font-weight: normal;"></span></h1>
<br/>
<div id="props"></div>
<script type="text/javascript">
// Get the app name
@ -36,14 +42,10 @@ var appname = ui.queryParams()['app'];
// Load the menu bar
ui.loadwidget('menu', '/menu.html?app=' + appname, ui.showbody);
</script>
<h1>App Edit <span id="appNameHeader" style="font-weight: normal;"></span></h1>
<br/>
<div id="props"></div>
<script type="text/javascript">
document.title = 'Settings - ' + appname;
$('h1').innerHTML = domaintitle(window.location.hostname);
$('appNameHeader').innerHTML = ' - ' + appname;
/**
* Display the properties editor for an app.
@ -55,11 +57,11 @@ function editapp(name) {
}
// Display the editor for the current app
document.title = 'App - ' + appname;
$('appNameHeader').innerHTML = ' - ' + appname;
editapp(appname);
ui.showbody();
</script>
</body>
</html>

View file

@ -27,7 +27,7 @@
<script type="text/javascript" src="/ui.js"></script>
<script type="text/javascript" src="/component.js"></script>
</head>
<body>
<body class="delayed">
<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;">
@ -45,6 +45,8 @@
<div>
<form id="appForm">
<table style="width: 100%;">
<tr><tr><td><b>App Icon:</b></td></tr>
<tr><td><img src="/public/app.png" style="width: 50px; height: 50px;"></td></tr>
<tr><tr><td><b>App Title:</b></td></tr>
<tr><td><input type="text" id="appTitle" size="80"/></td></tr>
<tr><tr><td><b>Category:</b></td></tr>
@ -97,6 +99,9 @@ function getapp(name) {
$('appUpdated').innerHTML = defdate;
$('appDescription').innerHTML = defdesc;
savedappentryxml = car(atom.writeATOMEntry(valuesToElements(mklist(appentry))));
// Show the page
ui.showbody();
});
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 635 B

After

Width:  |  Height:  |  Size: 258 B

Before After
Before After

Binary file not shown.

View file

@ -0,0 +1,32 @@
<!--
* 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.
-->
<html>
<head>
<title>frame</title>
<meta name="viewport" content="width=device-width user-scalable=no initial-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
<link rel="stylesheet" type="text/css" href="/ui.css"/>
</head>
<body style="margin:3px; padding: 0px; background-color: #dcdcdc;">
<div>frame ...</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

View file

@ -18,7 +18,7 @@
-->
<html>
<head>
<title>App Edit - Sorry</title>
<title>Sorry</title>
<meta name="viewport" content="width=device-width user-scalable=no initial-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
@ -29,20 +29,27 @@
<body class="delayed">
<div id="menu"></div>
<script type="text/javascript">
// Load the menu bar
ui.loadwidget('menu', '/menu.html', ui.showbody);
</script>
<h1>App Edit</h1>
<h1 id="h1"></h1>
<br/>
<div class="hd1">Sorry, you're not authorized to view this page.</div>
<form name="signout" action="/public/notauth.html" method="GET">
</form>
<script type="text/javascript">
// Load the menu bar
if (!issubdomain(window.location.hostname))
ui.loadwidget('menu', '/menu.html', ui.showbody);
$('h1').innerHTML = domaintitle(window.location.hostname);
ui.showbody();
function submitSignout() {
document.cookie = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';path=/;secure=TRUE';
var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE';
document.cookie = reset;
document.signout.submit();
return true;
}
@ -50,7 +57,6 @@ function submitSignout() {
if (window.top.location.pathname != '/public/notauth.html')
submitSignout();
</script>
</form>
</body>
</html>

View file

@ -18,7 +18,7 @@
-->
<html>
<head>
<title>App Edit - Page not found</title>
<title>Page not found</title>
<meta name="viewport" content="width=device-width user-scalable=no initial-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
@ -29,16 +29,22 @@
<body class="delayed">
<div id="menu"></div>
<script type="text/javascript">
// Load the menu bar
ui.loadwidget('menu', '/menu.html', ui.showbody);
</script>
<h1>App Edit</h1>
<h1 id="h1"></h1>
<br/>
<div class="hd1">Sorry, that page was not found.</div>
<div>You may have clicked an expired link or mistyped the address.</div>
<script type="text/javascript">
// Load the menu bar
if (!issubdomain(window.location.hostname))
ui.loadwidget('menu', '/menu.html', ui.showbody);
$('h1').innerHTML = domaintitle(window.location.hostname);
ui.showbody();
</script>
</body>
</html>

View file

@ -18,7 +18,7 @@
-->
<html>
<head>
<title>App Edit - Oops</title>
<title>Oops</title>
<meta name="viewport" content="width=device-width user-scalable=no initial-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
@ -29,15 +29,21 @@
<body class="delayed">
<div id="menu"></div>
<h1 id="h1"></h1>
<br/>
<div class="hd1">Oops, something went wrong...</div>
<script type="text/javascript">
// Load the menu bar
ui.loadwidget('menu', '/menu.html', ui.showbody);
</script>
if (!issubdomain(window.location.hostname))
ui.loadwidget('menu', '/menu.html', ui.showbody);
<h1>App Edit</h1>
<br/>
<div class="hd1">Oops, something went wrong...</div>
$('h1').innerHTML = domaintitle(window.location.hostname);
ui.showbody();
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

View file

@ -0,0 +1,2 @@
User-agent: *
Disallow: /

View file

@ -22,6 +22,7 @@
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
<link rel="apple-touch-icon" href="/public/touchicon.png"/>
<link rel="stylesheet" type="text/css" href="/ui.css"/>
<script type="text/javascript" src="/util.js"></script>
<script type="text/javascript" src="/ui.js"></script>
@ -29,24 +30,30 @@
<body class="delayed">
<div id="menu"></div>
<script type="text/javascript">
// Load the menu bar
ui.loadwidget('menu', '/menu.html', ui.showbody);
</script>
<h1>App Edit</h1>
<h1 id="h1"></h1>
<br/>
<div id="store"></div>
<script type="text/javascript">
// Load the menu bar
ui.loadwidget('menu', '/menu.html', ui.showbody);
$('h1').innerHTML = domaintitle(window.location.hostname);
// Get the store category
var category = ui.queryParams()['category'];
if (isNil(category))
category = 'new';
// Load the store
$('store').innerHTML =
'<iframe id="storeFrame" style="height: 5000px; width: 100%; border: 0px;" scrolling="no" frameborder="0" src="store.html"></iframe>';
'<iframe id="storeFrame" style="height: 5000px; width: 100%; border: 0px;" scrolling="no" frameborder="0" src="store.html?category=' + category + '"></iframe>';
ui.showbody();
</script>
</body>
</html>

View file

@ -27,15 +27,11 @@
<script type="text/javascript" src="/ui.js"></script>
<script type="text/javascript" src="/component.js"></script>
</head>
<body>
<body class="delayed">
<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;">
<table style="width: 100%;">
<tr>
<th class="thl thr" style="padding-top: 4px; padding-bottom: 4px;">Cool Apps</th>
</tr>
</table>
<div id="catmenu"></div>
<div id="apps"></div>
<br/>
@ -43,7 +39,39 @@
<script type="text/javascript">
if (ui.isIE()) $('bodydiv').style.right = -20;
// Init service references
/**
* The current app category.
*/
var category = ui.queryParams()['category'];
if (isNil(category))
category = 'new';
/**
* Build store menu bar
*/
function catmenu() {
function catmenuitem(name, cat) {
var c = cat == category? "smenu" : "amenu";
return '<th class="thl thr" style="width: 30px; padding-top: 4px; padding-bottom: 4px; padding-right: 10px;">'
+ '<a href="/store/?category=' + cat + '" target="_parent"><span class="' + c + '">' + name + '</span></a></th>';
}
var m = '<table style="width: 100%;"><tr>';
m += catmenuitem('New Apps', 'new');
m += catmenuitem('Top Charts', 'top');
m += catmenuitem('Featured', 'featured');
m += catmenuitem('Services', 'services');
m += catmenuitem('Tests', 'tests');
m += '<th class="thl thr" style="width: 100%;"></th></tr></table>';
return m;
}
// Build store menu bar
$('catmenu').innerHTML = catmenu();
/**
* Service references.
*/
var editWidget = sca.component("EditWidget");
var store = sca.reference(editWidget, "store");
@ -56,14 +84,14 @@ function applink(appname) {
var port = ':' + window.location.port;
if (port == ':80' || port == ':443' || port == ':')
port = '';
var link = protocol + '//' + appname + '.' + host + port + '/index.html';
var link = protocol + '//' + appname + '.' + host + port + '/';
return link;
}
/**
* Get and display list of apps.
*/
function getapps(sync) {
function getapps(category, sync) {
function display(doc) {
var apps = '<div>';
var feed = car(elementsToValues(atom.readATOMFeed(mklist(doc))));
@ -73,7 +101,7 @@ function getapps(sync) {
title = cadr(assoc("'title", entry))
name = cadr(assoc("'id", entry))
author = 'joe@localhost';
hreflink = '<a href=\"' + applink(name) + '\" target=\"_parent\">';
hreflink = '<a href=\"' + applink(name) + '\" target=\"' + name + '\">';
apps += '<div class="box" style="width: 250px; display: inline-block; border: 1px; border-style: solid; border-color: #dcdcdc; border-collapse: collapse; margin: 5px; padding: 10px; vertical-align: top;">'
apps += '<table><tr>';
@ -92,19 +120,22 @@ function getapps(sync) {
}
apps += '</div>';
$('apps').innerHTML = apps;
// Show the page
ui.showbody();
}
if (sync) {
display(store.get('coolapps'));
display(store.get(category));
} else {
store.get('coolapps', function(doc) {
store.get(category, function(doc) {
display(doc);
});
}
}
// Get and display the list of apps
getapps(true);
getapps(category, true);
</script>
</body>

View file

@ -38,6 +38,8 @@ for n in `ls apps | awk '{ printf "apps/%s/htdocs\n", $1 }'`; do
ln -s ../../../htdocs/public "$n/public"
ln -s ../../../htdocs/data "$n/data"
ln -s ../../../htdocs/app/index.html "$n/index.html"
ln -s ../../../htdocs/robots.txt "$n/robots.txt"
ln -s ../../../htdocs/favicon.ico "$n/favicon.ico"
ln -s ../app.html "$n/app.html"
fi
done

View file

@ -109,6 +109,10 @@ Require all granted
AuthType None
Require all granted
</Location>
<Location /robots.txt>
AuthType None
Require all granted
</Location>
# Listen on HTTP port
Listen $listen

View file

@ -406,6 +406,13 @@ HTTPBindingClient.getHTTPRequest = function() {
var sca = {};
/**
* Return an HTTP client proxy.
*/
sca.httpclient = function(name, uri) {
return new HTTPBindingClient(name, uri);
};
/**
* Return a component proxy.
*/

View file

@ -20,6 +20,7 @@
body {
white-space: margin: 0px;
font-family: arial,sans-serif; font-style: normal; font-variant: normal; font-size: 13px;
-webkit-text-size-adjust: none;
}
.delayed {
@ -81,11 +82,11 @@ padding-left: 2px; padding-top: 2px; padding-right: 8px; white-space: normal; ve
}
.datatdl {
border-right: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; width: 10px;
border-right: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; width: 10px; vertical-align: top;
}
.datatdr {
border-left: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc;
border-left: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; vertical-align: top;
}
.datatable {
@ -99,19 +100,26 @@ opacity: .6;
filter: alpha(opacity=60);
}
iframe {
border: 0px; margin: 0px; padding: 0px;
}
.widgetframe {
visibility: hidden; width: 0px; height: 0px; border: 0px;
}
.loadedframe {
width: 100%; height: 100%; border: 0px;
margin: 0px; padding: 0px;
width: 100%; height: 100%;
}
.fakeframe {
padding: 3px; background-color: #dcdcdc; color: #000000;
}
input {
vertical-align: middle;
font-family: arial,sans-serif; font-style: normal; font-variant: normal; font-size: 13px;
-webkit-text-size-adjust: 140%;
-webkit-text-size-adjust: 100%;
}
textarea {

View file

@ -36,10 +36,11 @@ ui.isIE = function() {
/**
* Build a menu bar.
*/
ui.menu = function(name, href) {
function Menu(n, h) {
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) {
@ -54,11 +55,11 @@ ui.menu = function(name, href) {
}
if (complete(this.href) != complete(window.top.location.pathname))
return '<a href="' + this.href + '" target="_parent"><span class=amenu>' + this.name + '</span></a>';
return '<a href="' + this.href + '" target="_parent"><span class=smenu>' + this.name + '</span></a>';
return '<a href="' + this.href + '" target="' + this.target + '"><span class=amenu>' + this.name + '</span></a>';
return '<a href="' + this.href + '" target="' + this.target + '"><span class=smenu>' + this.name + '</span></a>';
};
}
return new Menu(name, href);
return new Menu(name, href, target);
};
ui.menubar = function(left, right) {
@ -295,7 +296,6 @@ ui.csspos = function(p) {
* Convert a list of elements to an HTML table.
*/
ui.datatable = function(l) {
log('datatable', writeValue(l));
function indent(i) {
if (i == 0)
@ -308,22 +308,29 @@ ui.datatable = function(l) {
return '';
var e = car(l);
// Convert a list of simple values into a list of name value pairs
if (!isList(e))
return rows(expandElementValues("'value", l), i);
// Convert a list of complex values into a list of name value pairs
if (isList(car(e)))
return rows(expandElementValues("'value", l), i);
// Generate table row for a simple element value
if (elementHasValue(e)) {
var v = elementValue(e);
if (!isList(v)) {
return '<tr><td class="datatdl">' + indent(i) + elementName(e).slice(1) + '</td>' +
'<td class="datatdr">' + v + '</td></tr>' +
'<td class="datatdr tdw">' + v + '</td></tr>' +
rows(cdr(l), i);
}
return rows(expandElementValues(elementName(e), v), i) + rows(cdr(l), i);
}
// Generate table row for an element with children
return '<tr><td class="datatdl">' + indent(i) + elementName(e).slice(1) + '</td>' +
'<td class="datatdr">' + '</td></tr>' +
'<td class="datatdr tdw">' + '</td></tr>' +
rows(elementChildren(e), i + 1) +
rows(cdr(l), i);
}

View file

@ -20,6 +20,7 @@
body {
white-space: margin: 0px;
font-family: arial,sans-serif; font-style: normal; font-variant: normal; font-size: 13px;
-webkit-text-size-adjust: none;
}
.delayed {
@ -81,11 +82,11 @@ padding-left: 2px; padding-top: 2px; padding-right: 8px; white-space: normal; ve
}
.datatdl {
border-right: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; width: 10px;
border-right: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; width: 10px; vertical-align: top;
}
.datatdr {
border-left: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc;
border-left: 1px; border-top: 1px; border-bottom: 1px; border-style: solid; border-color: #dcdcdc; vertical-align: top;
}
.datatable {
@ -99,19 +100,26 @@ opacity: .6;
filter: alpha(opacity=60);
}
iframe {
border: 0px; margin: 0px; padding: 0px;
}
.widgetframe {
visibility: hidden; width: 0px; height: 0px; border: 0px;
}
.loadedframe {
width: 100%; height: 100%; border: 0px;
margin: 0px; padding: 0px;
width: 100%; height: 100%;
}
.fakeframe {
padding: 3px; background-color: #dcdcdc; color: #000000;
}
input {
vertical-align: middle;
font-family: arial,sans-serif; font-style: normal; font-variant: normal; font-size: 13px;
-webkit-text-size-adjust: 140%;
-webkit-text-size-adjust: 100%;
}
textarea {

View file

@ -285,6 +285,43 @@ function properties(o) {
return a;
}
/**
* Convert a host name to a domain name.
*/
function domainname(host) {
var h = reverse(host.split('.'));
return reverse(mklist(car(h), cadr(h))).join('.');
}
/**
* Return true if a host name is a subdomain.
*/
function issubdomain(host) {
return host.split('.').length > 2;
}
/**
* Convert a host name to a domain name title.
*/
function domaintitle(host) {
var h = reverse(host.split('.'));
var d = isNil(cdr(h))? car(h) : cadr(h);
return d.substr(0, 1).toUpperCase() + d.substr(1);
}
/**
* Format a string like Python format.
*/
function format() {
var i = 0;
var s = '';
for (a in arguments) {
s = i == 0? arguments[a] : s.replace('{' + a + '}', arguments[a]);
i++;
}
return s;
}
/**
* Functions with side effects. Use with moderation.
*/