blob: bc8eb78e7d0d7899a5f0efd9e2ccde22ed2d1bb1 [file] [log] [blame]
<!--
* 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>App</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"/>
<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>
<script type="text/javascript" src="/xmlutil.js"></script>
<script type="text/javascript" src="/atomutil.js"></script>
<script type="text/javascript" src="/jsonutil.js"></script>
<script type="text/javascript" src="/scdl.js"></script>
<script type="text/javascript" src="/ui.js"></script>
<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;
/**
* Page, every and location components.
*/
var pagecomp = sca.httpclient('page', '/page');
var everycomp = sca.httpclient('every', '/every');
var locationcomp = sca.httpclient('location', '/location');
/**
* Find a named value in a tree of elements.
*/
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') {
var t = datatext(dv);
car(childElements(e)).innerHTML = t;
return t;
}
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') {
var t = datatext(dv);
car(childElements(e)).value = t;
map(function(n) { if (n.nodeName == "SPAN") n.innerHTML = t; return n; }, nodeList(e.childNodes));
return t;
}
if (e.className == 'list') {
var t = datatext(dv);
var ce = car(childElements(car(childElements(e))));
ce.value = t;
ce.innerHTML = t;
return t;
}
if (e.className == 'table') {
var t = ui.datatable(elementChildren(dv));
car(childElements(e)).innerHTML = t;
return 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 '';
};
/**
* Display data on the app page.
*/
function displaydata(l) {
// Update the widgets values
function updatewidget(e) {
var dv = datavalue(l, "'" + e.id);
if (dv == null || isNil(dv))
return e;
setwidgetvalue(e, dv);
return e;
}
map(updatewidget, filter(function(e) { return !isNil(e.id); }, nodeList(ui.elementByID($('app'), 'page').childNodes)));
return true;
}
/**
* Display data from a document on the app page.
*/
function displaydoc(doc) {
if (isNil(doc))
return true;
if (json.isJSON(mklist(doc)))
return displaydata(json.readJSON(mklist(doc)));
if (atom.isATOMEntry(mklist(doc)))
return displaydata(atom.readATOMEntry(mklist(doc)));
if (atom.isATOMFeed(mklist(doc)))
return displaydata(atom.readATOMFeed(mklist(doc)));
return displaydata(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="getpagedata()"></iframe>';
</script>
</body>
</html>