Simplify page navigations and optimize layout and event handling on touch devices. Optimize caching and minimize Ajax calls.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1126297 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
09fdc02e7a
commit
49f4223605
17 changed files with 801 additions and 458 deletions
sca-cpp/trunk
.gitignore
modules/edit/htdocs
1
sca-cpp/trunk/.gitignore
vendored
1
sca-cpp/trunk/.gitignore
vendored
|
@ -57,6 +57,7 @@ config.sub
|
|||
config.status
|
||||
config.js
|
||||
all.js
|
||||
intro*.png
|
||||
depcomp
|
||||
install-sh
|
||||
ltmain.sh
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
CACHE MANIFEST
|
||||
|
||||
# Common resources
|
||||
all-min.js
|
||||
config.js
|
||||
ui-min.css
|
||||
|
||||
# App resources
|
||||
app.html
|
||||
data/index.html
|
||||
favicon.ico
|
||||
index.html
|
||||
public/app.png
|
||||
public/iframe.html
|
||||
public/img.png
|
||||
public/notauth.html
|
||||
public/notfound.html
|
||||
public/notyet.html
|
||||
public/oops.html
|
||||
public/touchicon.png
|
||||
robots.txt
|
||||
|
||||
NETWORK:
|
||||
*
|
||||
|
25
sca-cpp/trunk/modules/edit/htdocs/app/cache-manifest.cmf.off
Normal file
25
sca-cpp/trunk/modules/edit/htdocs/app/cache-manifest.cmf.off
Normal file
|
@ -0,0 +1,25 @@
|
|||
CACHE MANIFEST
|
||||
|
||||
# Common resources
|
||||
/all-min.js
|
||||
/config.js
|
||||
/ui-min.css
|
||||
|
||||
# App resources
|
||||
/
|
||||
/app.html
|
||||
/data/index.html
|
||||
/favicon.ico
|
||||
/public/app.png
|
||||
/public/iframe.html
|
||||
/public/img.png
|
||||
/public/notauth.html
|
||||
/public/notfound.html
|
||||
/public/notyet.html
|
||||
/public/oops.html
|
||||
/public/touchicon.png
|
||||
/robots.txt
|
||||
|
||||
NETWORK:
|
||||
*
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
-->
|
||||
<html manifest="/cache-manifest.cmf">
|
||||
<html>
|
||||
<head>
|
||||
<title>App</title>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
|
||||
|
@ -37,20 +37,25 @@ document.title = window.location.hostname.split('.')[0];
|
|||
|
||||
<div id="app"></div>
|
||||
|
||||
<span id="appFrame"></span>
|
||||
<span id="appbuffer"></span>
|
||||
<span id="appebuffer"></span>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
if (ui.isIE()) $('bodydiv').style.right = -20;
|
||||
|
||||
/**
|
||||
* Start, stop, timer and geolocation components.
|
||||
* The main app div.
|
||||
*/
|
||||
var appdiv = $('app');
|
||||
|
||||
/**
|
||||
* Start, stop, timer and location components.
|
||||
*/
|
||||
var startcomp = sca.httpclient('start', '/start');
|
||||
var stopcomp = sca.httpclient('stop', '/stop');
|
||||
var timercomp = sca.httpclient('timer', '/timer');
|
||||
var geolocationcomp = sca.httpclient('geolocation', '/geolocation');
|
||||
var locationcomp = sca.httpclient('location', '/location');
|
||||
|
||||
/**
|
||||
* Find a named value in a tree of elements.
|
||||
|
@ -146,13 +151,13 @@ function setwidgetvalue(e, dv) {
|
|||
return t;
|
||||
}
|
||||
if (e.className == 'list') {
|
||||
var t = ui.datalist(mklist(dv));
|
||||
car(childElements(e)).innerHTML = t;
|
||||
var t = ui.datalist(isNil(dv)? mklist() : mklist(dv));
|
||||
e.innerHTML = t;
|
||||
return t;
|
||||
}
|
||||
if (e.className == 'table') {
|
||||
var t = ui.datatable(mklist(dv));
|
||||
car(childElements(e)).innerHTML = t;
|
||||
var t = ui.datatable(isNil(dv)? mklist() : mklist(dv));
|
||||
e.innerHTML = t;
|
||||
return t;
|
||||
}
|
||||
if (e.className == 'link') {
|
||||
|
@ -190,7 +195,7 @@ function displaydata(l) {
|
|||
return e;
|
||||
}
|
||||
|
||||
map(updatewidget, filter(function(e) { return !isNil(e.id); }, nodeList(ui.elementByID($('app'), 'page').childNodes)));
|
||||
map(updatewidget, filter(function(e) { return !isNil(e.id) && e.id.substring(0, 5) != 'page:'; }, nodeList(ui.elementByID(appdiv, 'page').childNodes)));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -219,10 +224,11 @@ function displaydoc(doc) {
|
|||
function bindwidgethandler(e) {
|
||||
if (e.className == 'button') {
|
||||
var b = car(childElements(e));
|
||||
b.onclick = function() { return buttonClickHandler(e.id); };
|
||||
b.name = e.id;
|
||||
b.onclick = function() { return buttonClickHandler(b.value); };
|
||||
return e;
|
||||
}
|
||||
if (e.className == 'button' || e.className == 'entry' || e.className == 'password' || e.className == 'checkbox') {
|
||||
if (e.className == 'entry' || e.className == 'password' || e.className == 'checkbox') {
|
||||
car(childElements(e)).name = e.id;
|
||||
return e;
|
||||
}
|
||||
|
@ -262,6 +268,15 @@ function fixupwidget(e) {
|
|||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set initial value of a widget.
|
||||
*/
|
||||
function initwidget(e) {
|
||||
if (!isNil(e.id) && e.id.substring(0, 5) != 'page:')
|
||||
setwidgetvalue(e, mklist());
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get app data from the main app page component.
|
||||
*/
|
||||
|
@ -291,6 +306,7 @@ function getpagedata() {
|
|||
|
||||
// Initial setup of a widget
|
||||
function setupwidget(e) {
|
||||
initwidget(e);
|
||||
fixupwidget(e);
|
||||
bindwidgethandler(e);
|
||||
}
|
||||
|
@ -298,17 +314,24 @@ function getpagedata() {
|
|||
// Get the component app data
|
||||
var doc = startcomp.get(window.location.search);
|
||||
try {
|
||||
$('app').innerHTML = $('appFrame').contentDocument.body.innerHTML;
|
||||
var appFrame = $('appFrame');
|
||||
if (!isNil(appFrame.contentDocument.body)) {
|
||||
appdiv.innerHTML = appFrame.contentDocument.body.innerHTML;
|
||||
} else {
|
||||
$('appebuffer').appendChild(appFrame.contentDocument.documentElement);
|
||||
appdiv.innerHTML = appebuffer.innerHTML;
|
||||
appebuffer.innerHTML = '';
|
||||
}
|
||||
|
||||
// Initial setup of the widgets
|
||||
map(setupwidget, filter(function(e) { return !isNil(e.id); }, nodeList(ui.elementByID($('app'), 'page').childNodes)));
|
||||
map(setupwidget, filter(function(e) { return !isNil(e.id); }, nodeList(ui.elementByID(appdiv, 'page').childNodes)));
|
||||
|
||||
// Display data on the page
|
||||
displaypage(doc);
|
||||
|
||||
// Get and eval the optional timer and location watch setup scripts
|
||||
evalcompinit(timercomp.get('setup'));
|
||||
evalcompinit(geolocationcomp.get('setup'));
|
||||
evalcompinit(locationcomp.get('setup'));
|
||||
return true;
|
||||
|
||||
} catch(e) {
|
||||
|
@ -339,7 +362,7 @@ function compquery() {
|
|||
return append(nodeList(n.childNodes), reduce(append, mklist(), map(childrenList, nodeList(n.childNodes))));
|
||||
}
|
||||
|
||||
var args = map(queryarg, filter(function(e) { return !isNil(e.id) && !isNil(inputvalue(e)); }, childrenList(ui.elementByID($('app'), 'page'))));
|
||||
var args = map(queryarg, filter(function(e) { return !isNil(e.id) && !isNil(inputvalue(e)); }, childrenList(ui.elementByID(appdiv, 'page'))));
|
||||
|
||||
// Append current location properties if known
|
||||
if (!isNil(geoposition)) {
|
||||
|
@ -378,6 +401,7 @@ function intervalHandler() {
|
|||
* Setup an interval timer.
|
||||
*/
|
||||
function setupIntervalHandler(msec) {
|
||||
intervalHandler();
|
||||
try {
|
||||
return setInterval(intervalHandler, msec);
|
||||
} catch(e) {
|
||||
|
@ -394,7 +418,7 @@ var geoposition = null;
|
|||
function locationHandler(pos) {
|
||||
try {
|
||||
geoposition = pos;
|
||||
return getcompdata(geolocationcomp, compquery());
|
||||
return getcompdata(locationcomp, compquery());
|
||||
} catch(e) {
|
||||
locationErrorHandler(e);
|
||||
}
|
||||
|
@ -431,7 +455,7 @@ function setupLocationHandler() {
|
|||
}
|
||||
|
||||
// Load the app frame
|
||||
$('app').innerHTML = '<iframe id="appFrame" class="widgetFrame" src="app.html" onload="getpagedata()"></iframe>';
|
||||
$('appbuffer').innerHTML = '<iframe id="appFrame" class="widgetframe" src="app.html" onload="getpagedata()"></iframe>';
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -1,36 +1,37 @@
|
|||
CACHE MANIFEST
|
||||
|
||||
# Common resources
|
||||
all-min.js
|
||||
config.js
|
||||
ui-min.css
|
||||
/all-min.js
|
||||
/config.js
|
||||
/ui-min.css
|
||||
|
||||
# App resources
|
||||
app/index.html
|
||||
clone/index.html
|
||||
data/index.html
|
||||
create/index.html
|
||||
data/index.html
|
||||
favicon.ico
|
||||
graph/graph.js
|
||||
graph/index.html
|
||||
home.png
|
||||
index.html
|
||||
menu.js
|
||||
page/index.html
|
||||
page/page.js
|
||||
public/app.png
|
||||
public/grid72.png
|
||||
public/iframe.html
|
||||
public/img.png
|
||||
public/notauth.html
|
||||
public/notfound.html
|
||||
public/notyet.html
|
||||
public/oops.html
|
||||
public/touchicon.png
|
||||
robots.txt
|
||||
stats/index.html
|
||||
store/index.html
|
||||
/
|
||||
/account/
|
||||
/app/
|
||||
/clone/
|
||||
/data/
|
||||
/create/
|
||||
/data/
|
||||
/favicon.ico
|
||||
/graph/graph.js
|
||||
/graph/
|
||||
/home.png
|
||||
/menu.js
|
||||
/page/
|
||||
/page/page.js
|
||||
/public/app.png
|
||||
/public/grid72.png
|
||||
/public/iframe.html
|
||||
/public/img.png
|
||||
/public/notauth.html
|
||||
/public/notfound.html
|
||||
/public/notyet.html
|
||||
/public/oops.html
|
||||
/public/touchicon.png
|
||||
/robots.txt
|
||||
/stats/
|
||||
/store/
|
||||
|
||||
NETWORK:
|
||||
*
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<table style="width: 100%;">
|
||||
<tr>
|
||||
<td><h1><span id="h1"></span><span id="appNameHeader"></span></h1></td>
|
||||
<td><h2><span id="h1"></span><span id="appNameHeader"></span></h2></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
@ -49,7 +49,7 @@
|
|||
<form id="cloneAppForm" style="position: absolute; top: 90px; left: 0px;">
|
||||
<table style="width: 100%;">
|
||||
<tr><td><b>New App Name:</b></td></tr>
|
||||
<tr><td><input type="text" id="appName" size="15" placeholder="Your app name"/> <span id="appDomain"></span></td></tr>
|
||||
<tr><td><input type="text" id="appName" size="15" autocapitalize="off" placeholder="Your app name"/> <span id="appDomain"></span></td></tr>
|
||||
<tr><tr><td style="padding-top: 6px;"><b>App Icon:</b></td></tr>
|
||||
<tr><td><img src="/public/app.png" style="width: 50px; height: 50px; vertical-align: top;"></td></tr>
|
||||
<tr><tr><td style="padding-top: 6px;"><b>Sharing:</b></td></tr>
|
||||
|
@ -89,11 +89,11 @@ function applink(appname) {
|
|||
// Set page titles
|
||||
var tclone = isNil(config.clone)? 'Clone' : config.clone;
|
||||
document.title = windowtitle(window.location.hostname) + ' - ' + tclone + ' - ' + appname;
|
||||
$('h1').innerHTML = hometitle(window.location.hostname);
|
||||
$('appNameHeader').innerHTML = ' - <a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '</a>';
|
||||
//$('h1').innerHTML = hometitle(window.location.hostname);
|
||||
$('appNameHeader').innerHTML = '<a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '.' + window.location.hostname + '</a>';
|
||||
$('th').innerHTML = tclone + ' this App';
|
||||
$('cloneAppOKButton').value = tclone;
|
||||
$('cloneAppOKButton').title = tclone + ' the app';
|
||||
$('cloneAppOKButton').title = tclone + ' this app';
|
||||
|
||||
// Load the menu bar
|
||||
displaymenu();
|
||||
|
@ -106,7 +106,7 @@ ui.showbody();
|
|||
|
||||
// Init service references
|
||||
var editWidget = sca.component("EditWidget");
|
||||
var dashboard = sca.reference(editWidget, "dashboard");
|
||||
var dashboards = sca.reference(editWidget, "dashboards");
|
||||
var apps = sca.reference(editWidget, "apps");
|
||||
|
||||
/**
|
||||
|
@ -138,11 +138,15 @@ $('cloneAppForm').onsubmit = function() {
|
|||
var name = $('appName').value;
|
||||
if (name == '')
|
||||
return false;
|
||||
|
||||
// Clone the app
|
||||
var title = $('appTitle').value;
|
||||
var app = mklist(mklist("'entry", mklist("'title", title != ''? title : name), mklist("'id", appname)));
|
||||
var entry = atom.writeATOMEntry(valuesToElements(app));
|
||||
dashboard.put(name, car(entry));
|
||||
window.open('/store/', '_self');
|
||||
dashboards.put(name, car(entry));
|
||||
|
||||
// Open it in the page editor
|
||||
window.open('/page/?app=' + name, '_self');
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -150,7 +154,7 @@ $('cloneAppForm').onsubmit = function() {
|
|||
* Cancel cloning an app.
|
||||
*/
|
||||
$('cloneAppCancelButton').onclick = function() {
|
||||
return window.open('/store/', '_self');
|
||||
window.open('/stats/?app=' + appname, '_self');
|
||||
};
|
||||
|
||||
// Get the current app
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<form id="createAppForm" style="position: absolute; top: 90px; left: 0px;">
|
||||
<table style="width: 100%;">
|
||||
<tr><td><b>App Name:</b></td></tr>
|
||||
<tr><td><input type="text" id="appName" size="15" placeholder="Your app name"/> <span id="appDomain"></span></td></tr>
|
||||
<tr><td><input type="text" id="appName" size="15" autocapitalize="off" placeholder="Your app name"/> <span id="appDomain"></span></td></tr>
|
||||
<tr><tr><td style="padding-top: 6px;"><b>App Icon:</b></td></tr>
|
||||
<tr><td><img src="/public/app.png" style="width: 50px; height: 50px; vertical-align: top;"></td></tr>
|
||||
<tr><tr><td style="padding-top: 6px;"><b>Sharing:</b></td></tr>
|
||||
|
@ -81,7 +81,8 @@ ui.showbody();
|
|||
|
||||
// Init service references
|
||||
var editWidget = sca.component("EditWidget");
|
||||
var dashboard = sca.reference(editWidget, "dashboard");
|
||||
var dashboards = sca.reference(editWidget, "dashboards");
|
||||
var apps = sca.reference(editWidget, "apps");
|
||||
|
||||
/**
|
||||
* Create an app.
|
||||
|
@ -90,11 +91,15 @@ $('createAppForm').onsubmit = function() {
|
|||
var name = $('appName').value;
|
||||
if (name == '')
|
||||
return false;
|
||||
|
||||
// Clone the '.new' app template
|
||||
var title = $('appTitle').value;
|
||||
var app = mklist(mklist("'entry", mklist("'title", title != ''? title : name), mklist("'id", name)));
|
||||
var app = mklist(mklist("'entry", mklist("'title", title != ''? title : name), mklist("'id", 'new')));
|
||||
var entry = atom.writeATOMEntry(valuesToElements(app));
|
||||
dashboard.put(name, car(entry));
|
||||
window.open('/store/', '_self');
|
||||
dashboards.put(name, car(entry));
|
||||
|
||||
// Open it in the page editor
|
||||
window.open('/page/?app=' + name, '_self');
|
||||
return false;
|
||||
};
|
||||
|
||||
|
|
|
@ -35,23 +35,25 @@ document.title = 'View - ' + window.location.hostname.split('.')[0] + '/' + cn;
|
|||
<body class="delayed" onorientationchange="ui.reload();">
|
||||
|
||||
<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;">
|
||||
|
||||
<div id="compLinkHeader" style="margin-top: 4px; margin-bottom: 4px;"></div>
|
||||
<div id="datadiv" style="position: relative; left: 0px; right: 0px;">
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
if (ui.isIE()) $('bodydiv').style.right = -20;
|
||||
|
||||
// Get the component name
|
||||
var cname = ui.queryParams()['component'];
|
||||
|
||||
/**
|
||||
* The current component.
|
||||
*/
|
||||
var cname = ui.queryParams()['component'];
|
||||
var comp = sca.component(cname);
|
||||
|
||||
/**
|
||||
* Display an HTML element.
|
||||
*/
|
||||
function display(e) {
|
||||
$('bodydiv').innerHTML = e;
|
||||
$('datadiv').innerHTML = e;
|
||||
|
||||
ui.showbody();
|
||||
return true;
|
||||
|
|
|
@ -41,6 +41,8 @@ graph.colors.red = '#ff0000';
|
|||
graph.colors.white = '#ffffff';
|
||||
graph.colors.yellow = '#ffff00';
|
||||
|
||||
graph.colors.link = '#598edd';
|
||||
|
||||
graph.colors.orange1 = '#ffbb00';
|
||||
graph.colors.green1 = '#96d333';
|
||||
graph.colors.blue1 = '#00c3c9';
|
||||
|
@ -54,7 +56,6 @@ graph.colors.lightgray1 = '#dcdcdc'
|
|||
* Default positions and sizes.
|
||||
*/
|
||||
var palcx = 2500;
|
||||
var trashcx = 2480;
|
||||
var proxcx = 20;
|
||||
var proxcy = 20;
|
||||
var buttoncx = 65;
|
||||
|
@ -150,53 +151,22 @@ graph.mkgraph = function(pos, cvalue, cadd, cdelete) {
|
|||
*/
|
||||
div.onmousedown = function(e) {
|
||||
|
||||
// On mouse controlled devices, engage the click component selection
|
||||
// logic right away
|
||||
if (typeof e.touches == 'undefined')
|
||||
div.onclick(e);
|
||||
|
||||
// Find draggable component
|
||||
graph.dragging = draggable(e.target);
|
||||
graph.selected = graph.dragging;
|
||||
if (graph.dragging == null) {
|
||||
|
||||
// Reset current selection
|
||||
cvalue.value = '';
|
||||
cvalue.disabled = true;
|
||||
cdelete.disabled = true;
|
||||
|
||||
// Trigger component select event
|
||||
svg.oncompselect('');
|
||||
var dragging = draggable(e.target);
|
||||
if (dragging == null || dragging != graph.selected)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Clone component from the palette
|
||||
var compos = scdl.composite(svg.compos);
|
||||
if (graph.dragging.id.substring(0, 8) == 'palette:') {
|
||||
graph.dragging = graph.clonepalette(graph.dragging, compos);
|
||||
graph.selected = graph.dragging;
|
||||
|
||||
// Move into the editing area and hide the palette
|
||||
var gpos = graph.relpos(graph.dragging);
|
||||
graph.move(graph.dragging, graph.mkpath().move(gpos.xpos() + palcx, gpos.ypos()));
|
||||
div.style.left = ui.pixpos(palcx * -1);
|
||||
}
|
||||
|
||||
// Cut wire to component
|
||||
if (graph.dragging.parentNode != svg)
|
||||
setElement(compos, graph.sortcompos(graph.cutwire(graph.dragging, compos, svg)));
|
||||
|
||||
// Bring component to the top
|
||||
graph.bringtotop(graph.dragging, svg);
|
||||
graph.dragging = dragging;
|
||||
|
||||
// Remember current mouse position
|
||||
var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
|
||||
graph.dragX = pos.screenX;
|
||||
graph.dragY = pos.screenY;
|
||||
|
||||
// Update the component name and property value fields
|
||||
cvalue.value = graph.hasproperty(graph.selected.comp)? graph.property(graph.selected.comp) : graph.selected.id;
|
||||
cvalue.disabled = false;
|
||||
cdelete.disabled = false;
|
||||
|
||||
// Trigger component select event
|
||||
svg.oncompselect(graph.selected.id);
|
||||
|
||||
if (e.preventDefault)
|
||||
e.preventDefault();
|
||||
else
|
||||
|
@ -216,45 +186,28 @@ graph.mkgraph = function(pos, cvalue, cadd, cdelete) {
|
|||
|
||||
if (graph.dragging.parentNode == svg && graph.dragging.id.substring(0, 8) != 'palette:') {
|
||||
var gpos = graph.relpos(graph.dragging);
|
||||
if (gpos.xpos() >= trashcx) {
|
||||
|
||||
// If component close enough to editing area, move it there
|
||||
if (gpos.xpos() < palcx)
|
||||
graph.move(graph.dragging, graph.mkpath().move(palcx, gpos.ypos()));
|
||||
// Add new dragged component to the composite
|
||||
if (isNil(graph.dragging.compos)) {
|
||||
var compos = scdl.composite(svg.compos);
|
||||
setElement(compos, graph.sortcompos(graph.addcomp(graph.dragging.comp, compos)));
|
||||
graph.dragging.compos = svg.compos;
|
||||
}
|
||||
|
||||
// Add new dragged component to the composite
|
||||
if (isNil(graph.dragging.compos)) {
|
||||
var compos = scdl.composite(svg.compos);
|
||||
setElement(compos, graph.sortcompos(graph.addcomp(graph.dragging.comp, compos)));
|
||||
graph.dragging.compos = svg.compos;
|
||||
}
|
||||
// Update component position
|
||||
setElement(graph.dragging.comp, graph.movecomp(graph.dragging.comp, graph.abspos(graph.dragging, svg)));
|
||||
|
||||
// Update component position
|
||||
// Wire component to neighboring reference
|
||||
if (!isNil(graph.dragging.svcpos)) {
|
||||
var compos = scdl.composite(svg.compos);
|
||||
setElement(compos, graph.sortcompos(graph.clonerefs(graph.wire(graph.dragging, compos, svg))));
|
||||
}
|
||||
|
||||
// Snap top level component position to grid
|
||||
if (graph.dragging.parentNode == svg) {
|
||||
var gpos = graph.relpos(graph.dragging);
|
||||
graph.move(graph.dragging, graph.mkpath().move(graph.gridsnap(gpos.xpos()), graph.gridsnap(gpos.ypos())));
|
||||
setElement(graph.dragging.comp, graph.movecomp(graph.dragging.comp, graph.abspos(graph.dragging, svg)));
|
||||
|
||||
// Wire component to neighboring reference
|
||||
if (!isNil(graph.dragging.svcpos)) {
|
||||
var compos = scdl.composite(svg.compos);
|
||||
setElement(compos, graph.sortcompos(graph.clonerefs(graph.wire(graph.dragging, compos, svg))));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Discard component dragged out of composite
|
||||
svg.removeChild(graph.dragging);
|
||||
if (!isNil(graph.dragging.compos)) {
|
||||
var compos = scdl.composite(svg.compos);
|
||||
setElement(compos, graph.sortcompos(graph.clonerefs(graph.gcollect(graph.removecomp(graph.dragging.comp, compos)))));
|
||||
}
|
||||
|
||||
// Reset current selection
|
||||
graph.selected = null;
|
||||
cvalue.value = '';
|
||||
cvalue.disabled = true;
|
||||
cdelete.disabled = true;
|
||||
|
||||
// Trigger component select event
|
||||
svg.oncompselect('');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,7 +215,14 @@ graph.mkgraph = function(pos, cvalue, cadd, cdelete) {
|
|||
graph.dragging = null;
|
||||
|
||||
// Refresh the composite
|
||||
graph.refresh(svg);
|
||||
var nodes = graph.refresh(svg);
|
||||
|
||||
// Reselected the previously selected component
|
||||
graph.selected = graph.findcompnode(scdl.name(graph.selected.comp), nodes);
|
||||
graph.compselect(graph.selected, true, cvalue, cdelete);
|
||||
|
||||
// Trigger component select event
|
||||
svg.oncompselect(graph.selected);
|
||||
|
||||
// Trigger composite change event
|
||||
svg.oncomposchange(false);
|
||||
|
@ -273,13 +233,79 @@ graph.mkgraph = function(pos, cvalue, cadd, cdelete) {
|
|||
div.ontouchend = div.onmouseup;
|
||||
|
||||
// Handle a mouse click event.
|
||||
div.onclick = function(e) {
|
||||
if (graph.dragging == null && (e.target == div || e.target == svg)) {
|
||||
div.onclick = svg.onclick = function(e) {
|
||||
|
||||
// Find selected component
|
||||
var selected = draggable(e.target);
|
||||
if (selected == null) {
|
||||
if (graph.selected != null) {
|
||||
|
||||
// Reset current selection
|
||||
graph.compselect(graph.selected, false, cvalue, cdelete);
|
||||
graph.selected = null;
|
||||
|
||||
// Trigger component select event
|
||||
svg.oncompselect(null);
|
||||
}
|
||||
|
||||
// Dismiss the palette
|
||||
if (ui.numpos(div.style.left) != (palcx * -1))
|
||||
if (e.target == div || e.target == svg && ui.numpos(div.style.left) != (palcx * -1))
|
||||
div.style.left = ui.pixpos(palcx * -1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ignore multiple click events
|
||||
if (selected == graph.selected)
|
||||
return true;
|
||||
if (selected.id.substring(0, 8) == 'palette:' && ui.numpos(div.style.left) != 0)
|
||||
return true;
|
||||
|
||||
// Deselect previously selected component
|
||||
graph.compselect(graph.selected, false, cvalue, cdelete);
|
||||
|
||||
// Clone component from the palette
|
||||
if (selected.id.substring(0, 8) == 'palette:') {
|
||||
var compos = scdl.composite(svg.compos);
|
||||
graph.selected = graph.clonepalette(selected, compos, svg);
|
||||
setElement(compos, graph.sortcompos(graph.addcomp(graph.selected.comp, compos)));
|
||||
graph.selected.compos = svg.compos;
|
||||
|
||||
// Move into the editing area and hide the palette
|
||||
var gpos = graph.relpos(graph.selected);
|
||||
graph.move(graph.selected, graph.mkpath().move(gpos.xpos() + palcx, gpos.ypos()));
|
||||
div.style.left = ui.pixpos(palcx * -1);
|
||||
|
||||
// Update component position
|
||||
setElement(graph.selected.comp, graph.movecomp(graph.selected.comp, graph.abspos(graph.selected, svg)));
|
||||
|
||||
// Refresh the composite
|
||||
var nodes = graph.refresh(svg);
|
||||
|
||||
// Reselect the previously selected component
|
||||
graph.selected = graph.findcompnode(scdl.name(graph.selected.comp), nodes);
|
||||
graph.compselect(graph.selected, true, cvalue, cdelete);
|
||||
|
||||
// Trigger component select event
|
||||
svg.oncompselect(graph.selected);
|
||||
|
||||
// Trigger composite change event
|
||||
svg.oncomposchange(true);
|
||||
|
||||
} else {
|
||||
graph.selected = selected;
|
||||
|
||||
// Select the component
|
||||
graph.compselect(graph.selected, true, cvalue, cdelete);
|
||||
|
||||
// Trigger component select event
|
||||
svg.oncompselect(graph.selected);
|
||||
}
|
||||
|
||||
if (e.preventDefault)
|
||||
e.preventDefault();
|
||||
else
|
||||
e.returnValue = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -290,15 +316,28 @@ graph.mkgraph = function(pos, cvalue, cadd, cdelete) {
|
|||
if (graph.dragging == null)
|
||||
return true;
|
||||
|
||||
// Get the mouse position
|
||||
var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
|
||||
if (pos.screenX == graph.dragX && pos.screenY == graph.dragY)
|
||||
return true;
|
||||
|
||||
// Cut wire to component
|
||||
if (graph.dragging.parentNode != svg) {
|
||||
var compos = scdl.composite(svg.compos);
|
||||
setElement(compos, graph.sortcompos(graph.cutwire(graph.dragging, compos, svg)));
|
||||
|
||||
// Bring component to the top
|
||||
graph.bringtotop(graph.dragging, svg);
|
||||
}
|
||||
|
||||
// Calculate new position of dragged element
|
||||
var gpos = graph.relpos(graph.dragging);
|
||||
var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
|
||||
var newX = gpos.xpos() + (pos.screenX - graph.dragX);
|
||||
var newY = gpos.ypos() + (pos.screenY - graph.dragY);
|
||||
if (newX >= 0)
|
||||
if (newX >= palcx)
|
||||
graph.dragX = pos.screenX;
|
||||
else
|
||||
newX = 0;
|
||||
newX = palcx;
|
||||
if (newY >= 0)
|
||||
graph.dragY = pos.screenY;
|
||||
else
|
||||
|
@ -319,19 +358,25 @@ graph.mkgraph = function(pos, cvalue, cadd, cdelete) {
|
|||
cvalue.onchange = function() {
|
||||
if (graph.selected == null)
|
||||
return false;
|
||||
if (g.parentNode.style.visibility == 'hidden')
|
||||
return false;
|
||||
|
||||
// Change component name and refactor references to it
|
||||
function changename() {
|
||||
var compos = scdl.composite(svg.compos);
|
||||
cvalue.value = graph.ucid(cvalue.value, compos);
|
||||
cvalue.value = graph.ucid(cvalue.value, compos, false);
|
||||
graph.selected.id = cvalue.value;
|
||||
setElement(compos, graph.sortcompos(graph.renamecomp(graph.selected.comp, compos, cvalue.value)));
|
||||
|
||||
// Trigger component select event
|
||||
svg.oncompselect(graph.selected.id);
|
||||
|
||||
// Refresh the composite
|
||||
graph.refresh(svg);
|
||||
var nodes = graph.refresh(svg);
|
||||
|
||||
// Reselected the previously selected component
|
||||
graph.selected = graph.findcompnode(scdl.name(graph.selected.comp), nodes);
|
||||
graph.compselect(graph.selected, true, cvalue, cdelete);
|
||||
|
||||
// Trigger component select event
|
||||
svg.oncompselect(graph.selected);
|
||||
|
||||
// Trigger composite change event
|
||||
svg.oncomposchange(true);
|
||||
|
@ -345,7 +390,14 @@ graph.mkgraph = function(pos, cvalue, cadd, cdelete) {
|
|||
cvalue.disabled = !graph.hasproperty(graph.selected.comp);
|
||||
|
||||
// Refresh the composite
|
||||
graph.refresh(svg);
|
||||
var nodes = graph.refresh(svg);
|
||||
|
||||
// Reselected the previously selected component
|
||||
graph.selected = graph.findcompnode(scdl.name(graph.selected.comp), nodes);
|
||||
graph.compselect(graph.selected, true, cvalue, cdelete);
|
||||
|
||||
// Trigger component select event
|
||||
svg.oncompselect(graph.selected);
|
||||
|
||||
// Trigger composite change event
|
||||
svg.oncomposchange(true);
|
||||
|
@ -359,23 +411,23 @@ graph.mkgraph = function(pos, cvalue, cadd, cdelete) {
|
|||
cdelete.onclick = function() {
|
||||
if (graph.selected == null)
|
||||
return false;
|
||||
if (graph.selected.id.substring(0, 8) != 'palette:' && !isNil(graph.selected.compos)) {
|
||||
if (graph.selected.id.substring(0, 8) != 'palette:') {
|
||||
|
||||
// Remove selected component
|
||||
var compos = scdl.composite(svg.compos);
|
||||
if (isNil(graph.selected.compos))
|
||||
setElement(compos, graph.sortcompos(graph.cutwire(graph.selected, compos, svg)));
|
||||
setElement(compos, graph.sortcompos(graph.clonerefs(graph.gcollect(graph.removecomp(graph.selected.comp, compos)))));
|
||||
|
||||
// Reset current selection
|
||||
graph.compselect(graph.selected, false, cvalue, cdelete);
|
||||
graph.selected = null;
|
||||
cvalue.value = '';
|
||||
cvalue.disabled = true;
|
||||
cdelete.disabled = true;
|
||||
|
||||
// Refresh the composite
|
||||
graph.refresh(svg);
|
||||
|
||||
// Trigger component select event
|
||||
svg.oncompselect('');
|
||||
svg.oncompselect(null);
|
||||
|
||||
// Trigger composite change event
|
||||
svg.oncomposchange(true);
|
||||
|
@ -511,10 +563,41 @@ graph.proptitlewidth = function(comp) {
|
|||
return width;
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw a component shape selection.
|
||||
*/
|
||||
graph.compselect = function(g, s, cvalue, cdelete) {
|
||||
if (isNil(g) || !s) {
|
||||
if (!isNil(cvalue)) {
|
||||
cvalue.value = '';
|
||||
cvalue.disabled = true;
|
||||
}
|
||||
if (!isNil(cdelete))
|
||||
cdelete.disabled = true;
|
||||
if (isNil(g))
|
||||
return true;
|
||||
g.contour.setAttribute('stroke', graph.colors.gray);
|
||||
g.contour.setAttribute('stroke-opacity', '0.20');
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isNil(cvalue)) {
|
||||
cvalue.value = graph.hasproperty(g.comp)? graph.property(g.comp) : g.id;
|
||||
cvalue.disabled = false;
|
||||
}
|
||||
if (!isNil(cdelete))
|
||||
cdelete.disabled = false;
|
||||
|
||||
g.contour.setAttribute('stroke', graph.colors.link);
|
||||
g.contour.setAttribute('stroke-opacity', '0.80');
|
||||
g.parentNode.appendChild(g);
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a node representing a component.
|
||||
*/
|
||||
graph.compnode = function(comp, cassoc, pos) {
|
||||
graph.compnode = function(comp, cassoc, pos, parentg) {
|
||||
|
||||
// Make the component and property title elements
|
||||
var title = graph.comptitle(comp);
|
||||
|
@ -554,9 +637,31 @@ graph.compnode = function(comp, cassoc, pos) {
|
|||
g.refpos = reverse(path.refpos);
|
||||
g.svcpos = reverse(path.svcpos);
|
||||
|
||||
// Store the contour in the component shape
|
||||
g.contour = contour;
|
||||
|
||||
// Handle onclick events
|
||||
g.onclick = parentg.onclick;
|
||||
|
||||
return g;
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the node representing a component.
|
||||
*/
|
||||
graph.findcompnode = function(name, nodes) {
|
||||
if (isNil(nodes))
|
||||
return null;
|
||||
if (isNil(car(nodes).comp))
|
||||
return graph.findcompnode(name, cdr(nodes));
|
||||
if (name == scdl.name(car(nodes).comp))
|
||||
return car(nodes);
|
||||
var node = graph.findcompnode(name, nodeList(car(nodes).childNodes));
|
||||
if (!isNil(node))
|
||||
return node;
|
||||
return graph.findcompnode(name, cdr(nodes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a graphical group.
|
||||
*/
|
||||
|
@ -598,6 +703,10 @@ graph.mkbutton = function(t, pos) {
|
|||
g.appendChild(shape);
|
||||
g.appendChild(contour);
|
||||
g.appendChild(title);
|
||||
|
||||
// Store the contour in the button shape
|
||||
g.contour = contour;
|
||||
|
||||
return g;
|
||||
};
|
||||
|
||||
|
@ -605,7 +714,7 @@ graph.mkbutton = function(t, pos) {
|
|||
* Return the relative position of a node.
|
||||
*/
|
||||
graph.relpos = function(e) {
|
||||
var pmatrix = e.parentNode.getCTM();
|
||||
var pmatrix = e.parentNode != null? e.parentNode.getCTM() : null;
|
||||
var matrix = e.getCTM();
|
||||
var curX = pmatrix != null? (Number(matrix.e) - Number(pmatrix.e)): Number(matrix.e);
|
||||
var curY = pmatrix != null? (Number(matrix.f) - Number(pmatrix.f)): Number(matrix.f);
|
||||
|
@ -1048,12 +1157,20 @@ graph.buttonpath = function(t) {
|
|||
/**
|
||||
* Render a SCDL composite into a list of component nodes.
|
||||
*/
|
||||
graph.composite = function(compos, pos) {
|
||||
graph.composite = function(compos, pos, aspalette, g) {
|
||||
var name = scdl.name(scdl.composite(compos));
|
||||
var comps = scdl.components(compos);
|
||||
var cassoc = scdl.nameToElementAssoc(comps);
|
||||
var proms = scdl.promotions(compos);
|
||||
|
||||
// Unmemoize any memoized info about components and their references.
|
||||
map(function(c) {
|
||||
unmemo(c);
|
||||
map(function(r) {
|
||||
unmemo(r);
|
||||
}, scdl.references(c));
|
||||
}, comps);
|
||||
|
||||
/**
|
||||
* Render a component.
|
||||
*/
|
||||
|
@ -1124,7 +1241,7 @@ graph.composite = function(compos, pos) {
|
|||
}
|
||||
|
||||
// Compute the component shape
|
||||
var gcomp = graph.compnode(comp, cassoc, pos);
|
||||
var gcomp = graph.compnode(comp, cassoc, pos, g);
|
||||
|
||||
// Render the components wired to the component references
|
||||
var rrefs = graph.rrefs(comp);
|
||||
|
@ -1201,10 +1318,17 @@ graph.composite = function(compos, pos) {
|
|||
// Render the promoted service components
|
||||
var rproms = renderproms(proms, cassoc, pos.clone().rmove(tabsz * 4, tabsz * 4));
|
||||
|
||||
if (name == 'palette') {
|
||||
if (aspalette) {
|
||||
|
||||
// Prefix ids of palette component elements with 'palette:' and
|
||||
// move them to the palette area
|
||||
return map(function(r) {
|
||||
r.id = 'palette:' + r.id;
|
||||
var gpos = graph.relpos(r);
|
||||
graph.move(r, graph.mkpath().move(gpos.xpos() - palcx, gpos.ypos()));
|
||||
return r;
|
||||
}, rproms);
|
||||
|
||||
// Prefix ids of palette component elements with 'palette:'
|
||||
return map(function(r) { r.id = 'palette:' + r.id; return r; }, rproms);
|
||||
} else {
|
||||
|
||||
// Link app component elements to the containing composite
|
||||
|
@ -1215,11 +1339,14 @@ graph.composite = function(compos, pos) {
|
|||
/**
|
||||
* Return a component unique id.
|
||||
*/
|
||||
graph.ucid = function(prefix, compos) {
|
||||
graph.ucid = function(prefix, compos, clone) {
|
||||
|
||||
// Build an assoc list keyed by component name
|
||||
var comps = map(function(c) { return mklist(scdl.name(c), c); }, namedElementChildren("'component", compos));
|
||||
|
||||
if (!clone && isNil(assoc(prefix, comps)))
|
||||
return prefix;
|
||||
|
||||
/**
|
||||
* Find a free component id.
|
||||
*/
|
||||
|
@ -1229,26 +1356,23 @@ graph.ucid = function(prefix, compos) {
|
|||
return ucid(p, id + 1);
|
||||
}
|
||||
|
||||
if (isNil(assoc(prefix, comps)))
|
||||
return prefix;
|
||||
|
||||
return ucid(prefix == ''? 'comp' : prefix, 2);
|
||||
return ucid(prefix == ''? 'comp' : prefix, 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Clone a palette component node.
|
||||
*/
|
||||
graph.clonepalette = function(e, compos) {
|
||||
graph.clonepalette = function(e, compos, g) {
|
||||
|
||||
// Clone the SCDL component and give it a unique name
|
||||
var comp = append(mklist(element, "'component", mklist(attribute, "'name", graph.ucid(scdl.name(e.comp), compos))),
|
||||
// Clone the SCDL component and give it a unique name
|
||||
var wcomp = append(mklist(element, "'component", mklist(attribute, "'name", graph.ucid(scdl.name(e.comp), compos, true))),
|
||||
filter(function(c) { return !(isAttribute(c) && attributeName(c) == "'name")}, elementChildren(e.comp)));
|
||||
var x = '<composite xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1">' + writeXML(mklist(comp), false) + '</composite>';
|
||||
var compos = readXML(mklist(x));
|
||||
comp = car(scdl.components(compos));
|
||||
var x = '<composite>' + writeXML(mklist(wcomp), false) + '</composite>';
|
||||
var rcompos = readXML(mklist(x));
|
||||
var comp = car(scdl.components(rcompos));
|
||||
|
||||
// Make a component node
|
||||
var gcomp = graph.compnode(comp, mklist(), graph.mkpath());
|
||||
var gcomp = graph.compnode(comp, mklist(), graph.mkpath(), g);
|
||||
graph.move(gcomp, graph.relpos(e));
|
||||
e.parentNode.appendChild(gcomp);
|
||||
|
||||
|
@ -1261,11 +1385,18 @@ graph.clonepalette = function(e, compos) {
|
|||
graph.movecomp = function(comp, pos) {
|
||||
if (isNil(pos))
|
||||
return append(mklist(element, "'component"),
|
||||
filter(function(e) { return !(isAttribute(e) && (attributeName(e) == "'t:x" || attributeName(e) == "'t:y")); }, elementChildren(comp)));
|
||||
return append(mklist(element, "'component", mklist(attribute, "'t:x", '' + (pos.xpos() - palcx)), mklist(attribute, "'t:y", '' + pos.ypos())),
|
||||
filter(function(e) { return !(isAttribute(e) && (attributeName(e) == "'t:x" || attributeName(e) == "'t:y")); }, elementChildren(comp)));
|
||||
filter(function(e) { return !(isAttribute(e) && (attributeName(e) == "'x" || attributeName(e) == "'y")); }, elementChildren(comp)));
|
||||
return append(mklist(element, "'component", mklist(attribute, "'x", '' + (pos.xpos() - palcx)), mklist(attribute, "'y", '' + pos.ypos())),
|
||||
filter(function(e) { return !(isAttribute(e) && (attributeName(e) == "'x" || attributeName(e) == "'y")); }, elementChildren(comp)));
|
||||
};
|
||||
|
||||
/**
|
||||
* Align a pos along a 10pixel grid.
|
||||
*/
|
||||
graph.gridsnap = function(x) {
|
||||
return Math.round(x / 10) * 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort elements of a composite.
|
||||
*/
|
||||
|
@ -1356,7 +1487,7 @@ graph.clonerefs = function(compos) {
|
|||
// reference at the end of the list
|
||||
var cc = append(
|
||||
filter(function(e) { return !(elementName(e) == "'reference" && scdl.target(e) == null); }, elementChildren(c)),
|
||||
mklist(mklist(element, "'reference", mklist(attribute, "'name", scdl.name(car(refs))), mklist(attribute, "'t:clonable", "true"))));
|
||||
mklist(mklist(element, "'reference", mklist(attribute, "'name", scdl.name(car(refs))), mklist(attribute, "'clonable", "true"))));
|
||||
return append(mklist(element, "'component"), cc);
|
||||
|
||||
}, elementChildren(compos)));
|
||||
|
@ -1535,10 +1666,11 @@ graph.hide = function(g) {
|
|||
*/
|
||||
graph.refresh = function(g) {
|
||||
|
||||
// Remove nodes and redisplay the composite associated with the graph
|
||||
// Remove existing nodes from the graph
|
||||
map(function(n) { if (!isNil(n.comp) && n.id.substr(0, 8) != 'palette:') { g.removeChild(n); } return n; }, nodeList(g.childNodes));
|
||||
graph.display(graph.composite(g.compos, graph.mkpath().move(palcx,0)), g);
|
||||
return g;
|
||||
|
||||
// Redisplay the composite associated with the graph
|
||||
return graph.display(graph.composite(g.compos, graph.mkpath().move(palcx,0), false, g), g);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -37,32 +37,45 @@
|
|||
|
||||
<table style="width: 100%;">
|
||||
<tr>
|
||||
<td><h1><span id="h1"></span><span id="appNameHeader"></span></h1></td>
|
||||
<td style="vertical-align: middle; text-align: right;"><span id="saveStatus" style="font-weight: bold; color: #808080;">Saved</span></td>
|
||||
<td><h2><span id="h1"></span><span id="appNameHeader"></span></h2></td>
|
||||
<td style="vertical-align: middle; text-align: right; padding-right: 2px;"><span id="saveStatus" style="font-weight: bold; color: #808080;">Saved</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table style="width: 100%;">
|
||||
<tr>
|
||||
<th class="thr thl" style="padding-left: 2px; padding-right: 2px;">
|
||||
<input id="compValue" type="text" value="" title="Component value" placeholder="Name" style="position: relative; width: 170px;"/>
|
||||
<span id="deleteComponentButton" title="Delete a component" class="redbutton" style="font-weight: bold; font-size: 16px; color: #808080; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">-</span>
|
||||
<span id="addComponentButton" title="Add a component" class="greenbutton" style="font-weight: bold; font-size: 16px; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">+</span>
|
||||
<span id="playComponentButton" title="View component value" class="bluebutton" style="font-weight: bold; font-size: 16px; color: #808080; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">></span>
|
||||
<th class="thr thl" style="padding-left: 2px; padding-right: 2px; width: 100%">
|
||||
<input id="compValue" type="text" value="" title="Component value" autocapitalize="off" placeholder="Value" style="position: relative; width: 100%;"/>
|
||||
</th>
|
||||
|
||||
<th class="thl thr" style="text-align: right; padding-right: 2px;">
|
||||
<span id="deleteCompButton" title="Delete a component" class="redbutton" style="font-weight: bold; font-size: 16px; color: #808080; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">-</span>
|
||||
|
||||
<span id="addCompButton" title="Add a component" class="greenbutton" style="font-weight: bold; font-size: 16px; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">+</span>
|
||||
|
||||
<span id="playCompButton" title="View component value" class="bluebutton" style="font-weight: bold; font-size: 16px; color: #808080; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">></span>
|
||||
</th>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div id="dataDiv" style="position:absolute; top: 95px; left: 0px; right: 0px; height: 5000px; visibility: hidden">
|
||||
<div id="playdiv" style="position:absolute; top: 95px; left: 0px; right: 0px; height: 5000px; visibility: hidden">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
// Get the app name
|
||||
var appname = ui.queryParams()['app'];
|
||||
if (isNil(appname))
|
||||
window.open('/', '_self');
|
||||
var ispalette = false;
|
||||
if (isNil(appname)) {
|
||||
appname = ui.queryParams()['palette'];
|
||||
if (isNil(appname))
|
||||
window.open('/', '_self');
|
||||
|
||||
// Edit a palette instead of a regular app
|
||||
ispalette = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the link to an app.
|
||||
|
@ -79,41 +92,65 @@ function applink(appname) {
|
|||
|
||||
// Set page titles
|
||||
document.title = windowtitle(window.location.hostname) + ' - ' + (isNil(config.compose)? 'Composition' : config.compose) + ' - ' + appname;
|
||||
$('h1').innerHTML = hometitle(window.location.hostname);
|
||||
$('appNameHeader').innerHTML = ' - <a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '</a>';
|
||||
//$('h1').innerHTML = hometitle(window.location.hostname);
|
||||
$('appNameHeader').innerHTML = '<a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '.' + window.location.hostname + '</a>';
|
||||
|
||||
// Load the menu bar
|
||||
displaymenu();
|
||||
|
||||
/**
|
||||
* Component value field, add, delete and play buttons.
|
||||
*/
|
||||
var cvalue = $('compValue');
|
||||
var cadd = $('addCompButton');
|
||||
var cdelete = $('deleteCompButton');
|
||||
var cplay = $('playCompButton');
|
||||
|
||||
/**
|
||||
* Adjust field size.
|
||||
*/
|
||||
function resizeFields() {
|
||||
cvalue.style.width = '0px';
|
||||
cvalue.style.width = ui.pixpos(cvalue.parentNode.clientWidth - 18);
|
||||
return true;
|
||||
}
|
||||
|
||||
resizeFields();
|
||||
window.onresize = resizeFields;
|
||||
|
||||
// Show the page
|
||||
ui.showbody();
|
||||
|
||||
// Init componnent references
|
||||
var editWidget = sca.component("EditWidget");
|
||||
var palettes = sca.reference(editWidget, "palettes");
|
||||
var composites = sca.reference(editWidget, "composites");
|
||||
var composites = sca.reference(editWidget, ispalette? "palettes" : "composites");
|
||||
|
||||
// Setup remote log
|
||||
//rconsole = sca.defun(sca.reference(editWidget, "log"), "log");
|
||||
|
||||
/**
|
||||
* The current app composite, corresponding saved XML content and component name.
|
||||
* Track the current app composite and corresponding saved XML content.
|
||||
*/
|
||||
var savedcomposxml = '';
|
||||
var composite;
|
||||
var compname = '';
|
||||
|
||||
/**
|
||||
* Track the composition graph and whether it's visible or not.
|
||||
* Track the composition graph, whether it's visible or not and the selected component.
|
||||
*/
|
||||
var g;
|
||||
var gdiv;
|
||||
var bg;
|
||||
var gvisible = true;
|
||||
var gcomp = null;
|
||||
var pdiv = $('playdiv');
|
||||
|
||||
// Track the palettes
|
||||
/**
|
||||
* Track the palettes.
|
||||
*/
|
||||
var gpalettes = new Array();
|
||||
var spalette = 'control';
|
||||
var bpalette = null;
|
||||
|
||||
/**
|
||||
* Return the composite in an ATOM entry.
|
||||
|
@ -139,11 +176,13 @@ function getapp(name, g) {
|
|||
if (isNil(composite)) {
|
||||
|
||||
// Create a default empty composite if necessary
|
||||
var x = '<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"' +
|
||||
var x = '<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" ' +
|
||||
'targetNamespace="http://app" name="app"></composite>';
|
||||
composite = readXML(mklist(x));
|
||||
}
|
||||
graph.edit(name, composite, graph.composite(composite, graph.mkpath().move(palcx,0)), oncomposchange, oncompselect, g);
|
||||
|
||||
// Display the composite
|
||||
graph.edit(name, composite, graph.composite(composite, graph.mkpath().move(palcx,0), false, g), oncomposchange, oncompselect, g);
|
||||
|
||||
// Track the saved composite XML
|
||||
savedcomposxml = car(writeXML(composite, false));
|
||||
|
@ -161,7 +200,7 @@ function displaypalette(name, g, palette, gpalettes) {
|
|||
|
||||
// Get the palette from the server
|
||||
var doc = palettes.get(name);
|
||||
gpalettes[name] = graph.composite(atomcomposite(doc), graph.mkpath().move(80,0));
|
||||
gpalettes[name] = graph.composite(atomcomposite(doc), graph.mkpath().move(2580,0), true, g);
|
||||
}
|
||||
graph.display(gpalettes[name], g);
|
||||
return true;
|
||||
|
@ -177,7 +216,10 @@ function installpalette(name, pos, g, bg, palette, gpalettes) {
|
|||
b.onclick = function(e) {
|
||||
|
||||
// Swap the selected palette
|
||||
graph.compselect(bpalette, false);
|
||||
displaypalette(spalette, bg, palette, gpalettes);
|
||||
bpalette = b;
|
||||
graph.compselect(b, true, null, null);
|
||||
spalette = name;
|
||||
return displaypalette(spalette, g, palette, gpalettes);
|
||||
};
|
||||
|
@ -190,7 +232,10 @@ function installpalette(name, pos, g, bg, palette, gpalettes) {
|
|||
}
|
||||
|
||||
// Display the selected palette
|
||||
return displaypalette(name, g, palette, gpalettes);
|
||||
graph.compselect(b, true, null, null);
|
||||
displaypalette(name, g, palette, gpalettes);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -202,8 +247,9 @@ function save(savexml) {
|
|||
var entry = '<entry xmlns="http://www.w3.org/2005/Atom">' +
|
||||
'<title type="text">' + appname + '</title><id>' + appname + '</id><content type="application/xml">' +
|
||||
savedcomposxml + '</content></entry>';
|
||||
composites.put(appname, entry);
|
||||
$('saveStatus').innerHTML = 'Saved';
|
||||
composites.put(appname, entry, function(r) {
|
||||
$('saveStatus').innerHTML = 'Saved';
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -220,15 +266,14 @@ function oncomposchange(prop) {
|
|||
if (prop)
|
||||
return save(newxml);
|
||||
|
||||
// Autosave other changes after 3 seconds
|
||||
// Autosave other changes after 1 second
|
||||
$('saveStatus').innerHTML = 'Modified';
|
||||
setTimeout(function() {
|
||||
var savexml = car(writeXML(composite, false));
|
||||
if (savedcomposxml == savexml) {
|
||||
if (savedcomposxml == newxml) {
|
||||
$('saveStatus').innerHTML = 'Saved';
|
||||
return false;
|
||||
}
|
||||
return save(savexml);
|
||||
return save(newxml);
|
||||
}, 1000);
|
||||
return true;
|
||||
}
|
||||
|
@ -236,7 +281,7 @@ function oncomposchange(prop) {
|
|||
/**
|
||||
* Return the link to a component value.
|
||||
*/
|
||||
function compvaluelink(appname, cname) {
|
||||
function compdatalink(appname, cname) {
|
||||
if (cname == '' || isNil(cname))
|
||||
return '';
|
||||
var protocol = window.location.protocol;
|
||||
|
@ -249,9 +294,9 @@ function compvaluelink(appname, cname) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Return the link to a component raw data.
|
||||
* Return the link to a component.
|
||||
*/
|
||||
function compdebuglink(appname, cname) {
|
||||
function complink(appname, cname) {
|
||||
if (cname == '' || isNil(cname))
|
||||
return '';
|
||||
var protocol = window.location.protocol;
|
||||
|
@ -259,78 +304,81 @@ function compdebuglink(appname, cname) {
|
|||
var port = ':' + window.location.port;
|
||||
if (port == ':80' || port == ':443' || port == ':')
|
||||
port = '';
|
||||
var link = protocol + '//' + appname + '.' + host + port + '/components/' + cname;
|
||||
var link = protocol + '//' + appname + '.' + host + port + '/c/' + cname;
|
||||
return link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a component select event.
|
||||
*/
|
||||
function oncompselect(cname) {
|
||||
if (cname == compname)
|
||||
function oncompselect(gsel) {
|
||||
if (gsel == gcomp)
|
||||
return true;
|
||||
compname = cname;
|
||||
var link = compvaluelink(appname, cname);
|
||||
gcomp = gsel;
|
||||
var cname = isNil(gsel)? '' : gsel.id;
|
||||
var link = compdatalink(appname, cname);
|
||||
|
||||
function updateButton(b, v) {
|
||||
b.style.color = v? '#000000' : '#808080';
|
||||
}
|
||||
|
||||
updateButton($('deleteComponentButton'), link != '');
|
||||
updateButton($('playComponentButton'), link != '');
|
||||
updateButton(cdelete, link != '');
|
||||
updateButton(cplay, link != '');
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the result data of a component.
|
||||
*/
|
||||
function showdata(cname) {
|
||||
function showdata(gcomp) {
|
||||
if (!gvisible)
|
||||
return true;
|
||||
gvisible = false;
|
||||
$('playComponentButton').innerHTML = '<';
|
||||
if (isNil(gcomp))
|
||||
return true;
|
||||
cvalue.value = complink(appname, gcomp.id);
|
||||
cplay.innerHTML = '<';
|
||||
gdiv.style.visibility = 'hidden'
|
||||
var rdiv = $('dataDiv');
|
||||
rdiv.style.visibility = 'visible';
|
||||
rdiv.innerHTML = '<iframe id="dataFrame" style="position: relative; height: 5000px; width: 100%; border: 0px;" scrolling="no" frameborder="0" src="' +
|
||||
compvaluelink(appname, cname) + '"></iframe>';
|
||||
gvisible = false;
|
||||
pdiv.style.visibility = 'visible';
|
||||
pdiv.innerHTML = '<iframe id="dataFrame" style="position: relative; height: 5000px; width: 100%; border: 0px;" scrolling="no" frameborder="0" src="' +
|
||||
compdatalink(appname, gcomp.id) + '"></iframe>';
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the composition graph.
|
||||
*/
|
||||
function showgraph() {
|
||||
function showgraph(gcomp) {
|
||||
if (gvisible)
|
||||
return true;
|
||||
gvisible = true;
|
||||
$('playComponentButton').innerHTML = '>';
|
||||
var rdiv = $('dataDiv');
|
||||
rdiv.style.visibility = 'hidden';
|
||||
rdiv.innerHTML = '';
|
||||
cplay.innerHTML = '>';
|
||||
pdiv.style.visibility = 'hidden';
|
||||
pdiv.innerHTML = '';
|
||||
gdiv.style.visibility = 'visible'
|
||||
gvisible = true;
|
||||
graph.compselect(gcomp, true, cvalue, cdelete);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Play the current component.
|
||||
* Handle play component button event.
|
||||
*/
|
||||
$('playComponentButton').onclick = function() {
|
||||
if (compname == '')
|
||||
cplay.onclick = function() {
|
||||
if (gcomp == null)
|
||||
return false;
|
||||
if (!gvisible)
|
||||
return showgraph();
|
||||
return showdata(compname);
|
||||
return showgraph(gcomp);
|
||||
return showdata(gcomp);
|
||||
}
|
||||
|
||||
// Create editor graph area
|
||||
g = graph.mkgraph(graph.mkpath().move(-2500,95), $('compValue'), $('addComponentButton'), $('deleteComponentButton'));
|
||||
g = graph.mkgraph(graph.mkpath().move(-2500,95), cvalue, cadd, cdelete);
|
||||
gdiv = g.parentNode;
|
||||
bg = graph.mkgroup(graph.mkpath());
|
||||
|
||||
// Install the palettes
|
||||
var pos = graph.mkpath();
|
||||
installpalette('control', pos.rmove(5,0), g, bg, spalette, gpalettes);
|
||||
var pos = graph.mkpath().move(0, 0);
|
||||
bpalette = installpalette('control', pos.rmove(5,0), g, bg, spalette, gpalettes);
|
||||
installpalette('values', pos.rmove(0,35), g, bg, spalette, gpalettes);
|
||||
installpalette('lists', pos.rmove(0, 35), g, bg, spalette, gpalettes);
|
||||
installpalette('transform', pos.rmove(0, 35), g, bg, spalette, gpalettes);
|
||||
|
|
|
@ -37,20 +37,18 @@
|
|||
<table style="width: 100%;">
|
||||
<tr><td><h1><span id="h1"></span></h1></td></tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
<div style="margin-left: auto; margin-right: auto; text-align: center;">
|
||||
|
||||
<h1><span id="maintitle"><span></h1>
|
||||
<br/><br/><br/><br/>
|
||||
<div id="maintitle" style="font-size: 150%;"></div>
|
||||
|
||||
<div id="maindiagram"></div>
|
||||
<br/><br/><br/><br/>
|
||||
<div id="maindiagram"><div id="diagram" style="width: 320px; height: 280px; background: url(home.png); padding: 0px; margin: 0px auto;"></div></div>
|
||||
<br/>
|
||||
|
||||
<input type="button" class="greenbutton" style="font-size: 150%; font-weight: bold; font-style: italic; padding: 10px;" id="getstarted" title="Get Started" value="Get Started"/>
|
||||
|
||||
<br/><br/><br/>
|
||||
<div>Safari, Chrome, Firefox only for now.</div>
|
||||
<br/><br/>
|
||||
<div>Requires Safari 5+, Chrome 11+, Firefox 4+, IE 9+</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -65,13 +63,23 @@ $('h1').innerHTML = hometitle(window.location.hostname);
|
|||
displaymenu();
|
||||
|
||||
$('maintitle').innerHTML = isNil(config.maintitle)? 'Simple App Builder' : config.maintitle;
|
||||
$('maindiagram').innerHTML = isNil(config.maindiagram)? '<< insert diagram here >>' : config.maindiagram;
|
||||
$('getstarted').onclick = function() {
|
||||
return window.open('/store/', '_self');
|
||||
};
|
||||
|
||||
// Display the main diagram
|
||||
var diagram = $('diagram');
|
||||
var bgpos = 0;
|
||||
setInterval(function() {
|
||||
bgpos = bgpos -280;
|
||||
if (bgpos == -2800)
|
||||
bgpos = 0;
|
||||
diagram.style.backgroundPosition = '0px ' + ui.pixpos(bgpos);
|
||||
}, 2000);
|
||||
|
||||
// Show the page
|
||||
ui.showbody();
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
|
|
@ -27,13 +27,15 @@
|
|||
<link rel="stylesheet" type="text/css" href="/ui-min.css"/>
|
||||
<script type="text/javascript" src="/all-min.js"></script>
|
||||
</head>
|
||||
<body onorientationchange="ui.reload();">
|
||||
<body class="delayed" onorientationchange="ui.reload();">
|
||||
<div id="bodydiv" class="devicewidth">
|
||||
|
||||
<h1>Sign in</h1>
|
||||
|
||||
<form name="formSignin" onsubmit="submitSignin();" method="POST" action="/login/dologin/">
|
||||
<table border="0">
|
||||
<tr><td><b>Username:</b></td></tr>
|
||||
<tr><td><input type="text" id="httpd_username" name="httpd_username" value="" size="15" placeholder="Enter your user name" style="width: 300px;"/></td></tr>
|
||||
<tr><td><input type="text" id="httpd_username" name="httpd_username" value="" size="15" autocapitalize="off" placeholder="Enter your user name" style="width: 300px;"/></td></tr>
|
||||
<tr><td><b>Password:</b></td></tr>
|
||||
<tr><td><input type="password" name="httpd_password" value="" size="15" placeholder="Enter your password" style="width: 300px;"/></td></tr>
|
||||
<tr><td><input type="submit" value="Sign in" class="greenbutton" style="font-weight: bold;"/></td><td></td></tr>
|
||||
|
@ -41,7 +43,13 @@
|
|||
<input type="hidden" name="httpd_location" value="/"/>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
// Show the page
|
||||
ui.showbody();
|
||||
|
||||
function queryParams() {
|
||||
qp = new Array();
|
||||
qs = window.location.search.substring(1).split('&');
|
||||
|
|
|
@ -27,14 +27,22 @@
|
|||
<link rel="stylesheet" type="text/css" href="/ui-min.css"/>
|
||||
<script type="text/javascript" src="/all-min.js"></script>
|
||||
</head>
|
||||
<body onorientationchange="ui.reload();">
|
||||
<body class="delayed" onorientationchange="ui.reload();">
|
||||
<div id="bodydiv" class="devicewidth">
|
||||
|
||||
<h1>Sign out</h1>
|
||||
|
||||
<form name="signout" onsubmit="submitSignout();" action="/" method="GET">
|
||||
<input type="submit" id="signOut" value="Sign out" class="greenbutton" style="font-weight: bold"/>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
// Show the page
|
||||
ui.showbody();
|
||||
|
||||
function submitSignout() {
|
||||
var reset = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';domain=.' + domainname(window.location.hostname) + ';path=/;secure=TRUE';
|
||||
document.cookie = reset;
|
||||
|
|
|
@ -37,26 +37,28 @@
|
|||
|
||||
<table style="width: 100%;">
|
||||
<tr>
|
||||
<td><h1><span id="h1"></span><span id="appNameHeader"></span></h1></td>
|
||||
<td style="vertical-align: middle; text-align: right;"><span id="saveStatus" style="font-weight: bold; color: #808080;">Saved</span></td>
|
||||
<td><h2><span id="h1"></span><span id="appNameHeader"></span></h2></td>
|
||||
<td style="vertical-align: middle; text-align: right; padding-right: 2px;"><span id="saveStatus" style="font-weight: bold; color: #808080;">Saved</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table style="width: 100%;">
|
||||
<tr>
|
||||
<th class="thr thl" style="padding-left: 2px; padding-right: 2px;">
|
||||
<input id="widgetName" type="text" value="" title="Widget name" placeholder="Name" style="position: relative; width: 65px;"/>
|
||||
<input id="widgetText" type="text" value="" title="Widget text" placeholder="Text" style="position: relative; width: 120px;"/>
|
||||
<th class="thr thl" style="padding-left: 2px; padding-right: 2px; width: 100%;">
|
||||
<input id="widgetValue" type="text" value="" title="Widget value" autocapitalize="off" placeholder="Value" style="position: relative; width: 100%;"/>
|
||||
</th>
|
||||
|
||||
<th class="thl thr" style="text-align: right; padding-right: 2px;">
|
||||
<span id="deleteWidgetButton" title="Delete a Widget" class="redbutton" style="font-weight: bold; font-size: 16px; color: #808080; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">-</span>
|
||||
|
||||
<span id="addWidgetButton" title="Add a Widget" class="greenbutton" style="font-weight: bold; font-size: 16px; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">+</span>
|
||||
<!--
|
||||
<span id="playWidgetButton" title="View" class="bluebutton" style="font-weight: bold; font-size: 16px; color: #808080; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">></span>
|
||||
-->
|
||||
|
||||
<span id="playPageButton" title="View page" class="bluebutton" style="font-weight: bold; font-size: 16px; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">></span>
|
||||
</th>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div id="page" style="position: absolute; top: 95px; left: -2500px; right: 0px; height: 5000px;">
|
||||
<div id="editdiv" style="position: absolute; top: 95px; left: -2500px; right: 0px; height: 5000px;">
|
||||
|
||||
<div style="position: absolute; left: 2500px; top: 0px; right: 0px; height: 5000px; border:1px; border-style: solid; border-color: #a2bae7; background: url(/public/grid72.png);"></div>
|
||||
<div class="guide" style="position: absolute; left: 2500px; top: 0px; width: 320px; height: 460px;"></div>
|
||||
|
@ -85,6 +87,8 @@
|
|||
|
||||
</div>
|
||||
|
||||
<div id="playdiv" style="visibility: hidden; position: absolute; top: 95px; left: 0px; right: 0px; height: 5000px;"></div>
|
||||
|
||||
<div id="buffer" style="visibility: hidden; position: absolute; top: 0px; left: 0px; width: 0px; height: 0px"></div>
|
||||
|
||||
</div>
|
||||
|
@ -111,12 +115,35 @@ function applink(appname) {
|
|||
|
||||
// Set page titles
|
||||
document.title = windowtitle(window.location.hostname) + ' - Page - ' + appname;
|
||||
$('h1').innerHTML = hometitle(window.location.hostname);
|
||||
$('appNameHeader').innerHTML = ' - <a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '</a>';
|
||||
//$('h1').innerHTML = hometitle(window.location.hostname);
|
||||
$('appNameHeader').innerHTML = '<a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '.' + window.location.hostname + '</a>';
|
||||
|
||||
// Load the menu bar
|
||||
displaymenu();
|
||||
|
||||
/**
|
||||
* Page editor area, widget value field, add, delete and play page buttons.
|
||||
*/
|
||||
var ediv = $('editdiv');
|
||||
var evisible = true;
|
||||
var pdiv = $('playdiv');
|
||||
var wvalue = $('widgetValue');
|
||||
var wadd = $('addWidgetButton');
|
||||
var wdelete = $('deleteWidgetButton');
|
||||
var pplay = $('playPageButton');
|
||||
|
||||
/**
|
||||
* Adjust fields sizes.
|
||||
*/
|
||||
function resizeFields() {
|
||||
wvalue.style.width = '0px';
|
||||
wvalue.style.width = ui.pixpos(wvalue.parentNode.clientWidth - 18);
|
||||
return true;
|
||||
}
|
||||
|
||||
resizeFields();
|
||||
window.onresize = resizeFields;
|
||||
|
||||
// Show the page
|
||||
ui.showbody();
|
||||
|
||||
|
@ -138,15 +165,19 @@ function atompage(doc) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Track the current widget and page saved XHTML content.
|
||||
* Track the current page saved XHTML content.
|
||||
*/
|
||||
var widgetname = '';
|
||||
var savedpagexhtml = '';
|
||||
|
||||
/**
|
||||
* Track the current widget.
|
||||
*/
|
||||
var widget = null;
|
||||
|
||||
/**
|
||||
* Get and display an app page.
|
||||
*/
|
||||
function getpage(name, edit) {
|
||||
function getpage(name, ediv) {
|
||||
if (isNil(name))
|
||||
return false;
|
||||
return pages.get(name, function(doc) {
|
||||
|
@ -157,19 +188,19 @@ function getpage(name, edit) {
|
|||
|
||||
// Create a default empty page if necessary
|
||||
if (isNil(el))
|
||||
buffer.innerHTML = '<DIV id="page">\n</DIV>\n';
|
||||
buffer.innerHTML = '<div id="page"></div>';
|
||||
else
|
||||
buffer.innerHTML = writeStrings(writeXML(atompage(doc), false));
|
||||
|
||||
// Append page nodes to editor
|
||||
map(function(e) {
|
||||
edit.appendChild(e);
|
||||
ediv.appendChild(e);
|
||||
if (!isNil(e.style))
|
||||
e.style.left = ui.pixpos(ui.numpos(e.style.left) + 2500);
|
||||
return page.cover(e);
|
||||
}, nodeList(buffer.childNodes[0].childNodes));
|
||||
|
||||
savedpagexhtml = pagexhtml();
|
||||
savedpagexhtml = pagexhtml(ediv);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -177,22 +208,28 @@ function getpage(name, edit) {
|
|||
/**
|
||||
* Handle add widget button click event.
|
||||
*/
|
||||
$('addWidgetButton').onclick = function(e) {
|
||||
wadd.onclick = function(e) {
|
||||
// Show the widget palette
|
||||
$('page').style.left = ui.pixpos(0);
|
||||
ediv.style.left = ui.pixpos(0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the current page XHTML content.
|
||||
*/
|
||||
function pagexhtml() {
|
||||
function pagexhtml(ediv) {
|
||||
|
||||
// Copy page DOM to hidden buffer
|
||||
var edit = $('page');
|
||||
var buffer = $('buffer');
|
||||
buffer.innerHTML = '<DIV id="page">\n</DIV>\n'
|
||||
buffer.innerHTML = '<div id="page"></div>'
|
||||
var div = buffer.childNodes[0];
|
||||
div.innerHTML = edit.innerHTML;
|
||||
|
||||
// Capture the nodes inside the page div
|
||||
div.innerHTML = ediv.innerHTML;
|
||||
var nodes = nodeList(div.childNodes);
|
||||
map(function(e) {
|
||||
div.removeChild(e);
|
||||
return e;
|
||||
}, nodes);
|
||||
|
||||
// Filter out palette and editor artifacts, which are not
|
||||
// part of the page, as well as nodes positioned out the
|
||||
|
@ -204,7 +241,7 @@ function pagexhtml() {
|
|||
if (x < 0 || ui.numpos(e.style.top) < 0)
|
||||
return false;
|
||||
return true;
|
||||
}, nodeList(div.childNodes));
|
||||
}, nodes);
|
||||
|
||||
// Reposition nodes
|
||||
map(function(e) {
|
||||
|
@ -226,8 +263,7 @@ function pagexhtml() {
|
|||
return 0;
|
||||
});
|
||||
|
||||
// Append them back to the div in order
|
||||
div.innerHTML = '';
|
||||
// Append the sorted nodes back to the div in order
|
||||
map(function(e) {
|
||||
div.appendChild(e);
|
||||
return e;
|
||||
|
@ -242,20 +278,20 @@ function pagexhtml() {
|
|||
/**
|
||||
* Save the current page.
|
||||
*/
|
||||
function save() {
|
||||
function save(newxml) {
|
||||
$('saveStatus').innerHTML = 'Saving';
|
||||
|
||||
// Get the current page XHTML content
|
||||
savedpagexhtml = pagexhtml();
|
||||
savedpagexhtml = newxml;
|
||||
|
||||
// Update the page ATOM entry
|
||||
var entry = '<entry xmlns="http://www.w3.org/2005/Atom">' +
|
||||
'<title type="text">' + appname + '</title><id>' + appname + '</id><content type="application/xml">' +
|
||||
savedpagexhtml + '</content></entry>';
|
||||
newxml + '</content></entry>';
|
||||
|
||||
pages.put(appname, entry);
|
||||
if (savedpagexhtml == pagexhtml())
|
||||
pages.put(appname, entry, function(r) {
|
||||
$('saveStatus').innerHTML = 'Saved';
|
||||
});
|
||||
return true;
|
||||
};
|
||||
|
||||
|
@ -263,19 +299,22 @@ function save() {
|
|||
* Handle a page change event
|
||||
*/
|
||||
function onpagechange(prop) {
|
||||
if (savedpagexhtml == pagexhtml())
|
||||
var newxml = pagexhtml(ediv);
|
||||
if (savedpagexhtml == newxml)
|
||||
return false;
|
||||
$('saveStatus').innerHTML = 'Modified';
|
||||
|
||||
// Save property changes right away
|
||||
if (prop)
|
||||
return save();
|
||||
return save(newxml);
|
||||
|
||||
// Autosave other changes after 3 seconds
|
||||
// Autosave other changes after 1 second
|
||||
setTimeout(function() {
|
||||
if (savedpagexhtml == pagexhtml())
|
||||
if (savedpagexhtml == newxml) {
|
||||
$('saveStatus').innerHTML = 'Saved';
|
||||
return false;
|
||||
return save();
|
||||
}
|
||||
return save(newxml);
|
||||
}, 1000);
|
||||
return true;
|
||||
}
|
||||
|
@ -298,40 +337,68 @@ function compvaluelink(appname, cname) {
|
|||
/**
|
||||
* Handle a widget select event.
|
||||
*/
|
||||
function onwidgetselect(wname) {
|
||||
if (wname == widgetname)
|
||||
function onwidgetselect(w) {
|
||||
if (w == widget)
|
||||
return true;
|
||||
widgetname = wname;
|
||||
var link = compvaluelink(appname, wname);
|
||||
widget = w;
|
||||
var link = compvaluelink(appname, isNil(w)? '' : w.id);
|
||||
|
||||
function updateButton(b, v) {
|
||||
b.style.color = v? '#000000' : '#808080';
|
||||
}
|
||||
|
||||
updateButton($('deleteWidgetButton'), link != '');
|
||||
//updateButton($('playWidgetButton'), link != '');
|
||||
|
||||
updateButton(wdelete, link != '');
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Play the component associated with the current widget.
|
||||
* Play page in a frame.
|
||||
*/
|
||||
/*
|
||||
$('playWidgetButton').onclick = function() {
|
||||
var link = compvaluelink(appname, widgetname);
|
||||
if (link == '')
|
||||
return;
|
||||
return window.open(link, '_' + appname + '_' + widgetname);
|
||||
function playpage() {
|
||||
if (!evisible)
|
||||
return true;
|
||||
page.widgetselect(widget, false, wvalue, wdelete);
|
||||
page.selected = null;
|
||||
wvalue.value = applink(appname);
|
||||
pplay.innerHTML = '<';
|
||||
ediv.style.visibility = 'hidden'
|
||||
evisible = false;
|
||||
pdiv.style.visibility = 'visible';
|
||||
pdiv.innerHTML = '<iframe id="appFrame" style="position: relative; height: 5000px; width: 100%; border: 0px;" scrolling="no" frameborder="0" src="' +
|
||||
applink(appname) + '"></iframe>';
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the page editor.
|
||||
*/
|
||||
function showedit() {
|
||||
if (evisible)
|
||||
return true;
|
||||
pplay.innerHTML = '>';
|
||||
pdiv.style.visibility = 'hidden';
|
||||
pdiv.innerHTML = '';
|
||||
ediv.style.visibility = 'visible'
|
||||
evisible = true;
|
||||
page.widgetselect(widget, true, wvalue, wdelete);
|
||||
page.selected = widget;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle play page button event.
|
||||
*/
|
||||
pplay.onclick = function() {
|
||||
if (!evisible)
|
||||
return showedit();
|
||||
return playpage();
|
||||
}
|
||||
*/
|
||||
|
||||
// Initialize the page editor
|
||||
var edit = $('page');
|
||||
page.edit(edit, $('widgetName'), $('widgetText'), $('addWidgetButton'), $('deleteWidgetButton'), onpagechange, onwidgetselect);
|
||||
page.edit(ediv, wvalue, wadd, wdelete, onpagechange, onwidgetselect);
|
||||
|
||||
// Get and display the current app page
|
||||
getpage(appname, edit);
|
||||
getpage(appname, ediv);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -26,18 +26,16 @@ var page = {};
|
|||
* Default positions and sizes.
|
||||
*/
|
||||
var palcx = 2500;
|
||||
var trashcx = 2480;
|
||||
|
||||
/**
|
||||
* Init a page editor. Works with all browsers except IE.
|
||||
*/
|
||||
page.edit = function(elem, wname, wtext, wadd, wdelete, onchange, onselect) {
|
||||
page.edit = function(elem, wvalue, wadd, wdelete, onchange, onselect) {
|
||||
|
||||
// Track element dragging and selection
|
||||
page.dragging = null;
|
||||
page.selected = null;
|
||||
wname.disabled = true;
|
||||
wtext.disabled = true;
|
||||
wvalue.disabled = true;
|
||||
wdelete.disabled = true;
|
||||
|
||||
// Trigger widget select and page change events
|
||||
|
@ -49,59 +47,22 @@ page.edit = function(elem, wname, wtext, wadd, wdelete, onchange, onselect) {
|
|||
*/
|
||||
elem.onmousedown = function(e) {
|
||||
|
||||
// On mouse controlled devices, engage the click component selection
|
||||
// logic right away
|
||||
if (typeof e.touches == 'undefined')
|
||||
elem.onclick(e);
|
||||
|
||||
// Find a draggable element
|
||||
page.dragging = page.draggable(e.target, elem);
|
||||
page.selected = page.dragging;
|
||||
if (page.dragging == null) {
|
||||
|
||||
// Reset current selection
|
||||
wname.value = '';
|
||||
wname.disabled = true;
|
||||
wtext.value = '';
|
||||
wtext.disabled = true;
|
||||
wdelete.disabled = true;
|
||||
|
||||
// Trigger widget select event
|
||||
page.onwidgetselect('');
|
||||
var dragging = page.draggable(e.target, elem);
|
||||
if (dragging == null || dragging != page.selected)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Clone element dragged from palette
|
||||
if (page.dragging.id.substring(0, 8) == 'palette:') {
|
||||
page.dragging = page.clone(page.dragging);
|
||||
page.selected = page.dragging;
|
||||
|
||||
// Move into the editing area and hide the palette
|
||||
page.selected.style.left = ui.pixpos(ui.numpos(page.selected.style.left) + palcx);
|
||||
elem.style.left = ui.pixpos(palcx * -1);
|
||||
|
||||
// Bring it to the top
|
||||
page.bringtotop(page.dragging);
|
||||
|
||||
// Trigger page change event
|
||||
page.onpagechange(true);
|
||||
|
||||
} else {
|
||||
|
||||
// Bring it to the top
|
||||
page.bringtotop(page.dragging);
|
||||
}
|
||||
page.dragging = dragging;
|
||||
|
||||
// Remember mouse position
|
||||
var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
|
||||
page.dragX = pos.screenX;
|
||||
page.dragY = pos.screenY;
|
||||
|
||||
// Update the widget name and text fields
|
||||
wname.value = page.selected.id;
|
||||
wname.disabled = false;
|
||||
wtext.value = page.text(page.selected);
|
||||
wtext.disabled = !page.hastext(page.selected);
|
||||
wdelete.disabled = false;
|
||||
|
||||
// Trigger widget select event
|
||||
page.onwidgetselect(page.selected.id);
|
||||
|
||||
if (e.preventDefault)
|
||||
e.preventDefault();
|
||||
else
|
||||
|
@ -130,29 +91,6 @@ page.edit = function(elem, wname, wtext, wadd, wdelete, onchange, onselect) {
|
|||
// Fixup widget style
|
||||
page.fixupwidget(page.dragging);
|
||||
|
||||
// Discard element dragged out of page area
|
||||
if (ui.numpos(page.dragging.style.left) < palcx && page.dragging.id.substring(0, 8) != 'palette:') {
|
||||
if (ui.numpos(page.dragging.style.left) >= trashcx) {
|
||||
|
||||
// Unless it's close enough to page area, then move it there
|
||||
page.dragging.style.left = ui.pixpos(palcx);
|
||||
page.dragging.cover.style.left = ui.pixpos(palcx);
|
||||
} else {
|
||||
page.dragging.parentNode.removeChild(page.dragging);
|
||||
|
||||
// Reset current selection
|
||||
page.selected = null;
|
||||
wname.value = '';
|
||||
wname.disabled = true;
|
||||
wtext.value = '';
|
||||
wtext.disabled = true;
|
||||
wdelete.disabled = true;
|
||||
|
||||
// Trigger widget select event
|
||||
page.onwidgetselect('');
|
||||
}
|
||||
}
|
||||
|
||||
// Forget dragged element
|
||||
page.dragging = null;
|
||||
|
||||
|
@ -171,16 +109,20 @@ page.edit = function(elem, wname, wtext, wadd, wdelete, onchange, onselect) {
|
|||
if (page.dragging == null)
|
||||
return true;
|
||||
|
||||
// Get the mouse position
|
||||
var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
|
||||
if (pos.screenX == page.dragX && pos.screenY == page.dragY)
|
||||
return true;
|
||||
|
||||
// Compute position of dragged element
|
||||
var curX = ui.numpos(page.dragging.style.left);
|
||||
var curY = ui.numpos(page.dragging.style.top);
|
||||
var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
|
||||
var newX = curX + (pos.screenX - page.dragX);
|
||||
var newY = curY + (pos.screenY - page.dragY);
|
||||
if (newX >= 0)
|
||||
if (newX >= palcx)
|
||||
page.dragX = pos.screenX;
|
||||
else
|
||||
newX = 0;
|
||||
newX = palcx;
|
||||
if (newY >= 0)
|
||||
page.dragY = pos.screenY;
|
||||
else
|
||||
|
@ -201,32 +143,70 @@ page.edit = function(elem, wname, wtext, wadd, wdelete, onchange, onselect) {
|
|||
* Handle a mouse click event.
|
||||
*/
|
||||
elem.onclick = function(e) {
|
||||
if (page.dragging == null) {
|
||||
|
||||
// Find selected element
|
||||
var selected = page.draggable(e.target, elem);
|
||||
if (selected == null) {
|
||||
if (page.selected != null) {
|
||||
|
||||
// Reset current selection
|
||||
page.widgetselect(page.selected, false, wvalue, wdelete);
|
||||
page.selected = null;
|
||||
|
||||
// Trigger widget select event
|
||||
page.onwidgetselect(null);
|
||||
}
|
||||
|
||||
// Dismiss the palette
|
||||
if (ui.numpos(elem.style.left) != (palcx * -1))
|
||||
elem.style.left = ui.pixpos(palcx * -1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Deselect the previously selected element
|
||||
page.widgetselect(page.selected, false, wvalue, wdelete);
|
||||
|
||||
// Clone element dragged from palette
|
||||
if (selected.id.substring(0, 8) == 'palette:') {
|
||||
page.selected = page.clone(selected);
|
||||
|
||||
// Move into the editing area and hide the palette
|
||||
page.selected.style.left = ui.pixpos(ui.numpos(page.selected.style.left) + palcx);
|
||||
page.selected.cover.style.left = ui.pixpos(ui.numpos(page.selected.cover.style.left) + palcx);
|
||||
elem.style.left = ui.pixpos(palcx * -1);
|
||||
|
||||
// Bring it to the top
|
||||
page.bringtotop(page.selected);
|
||||
|
||||
// Trigger page change event
|
||||
page.onpagechange(true);
|
||||
|
||||
} else {
|
||||
|
||||
// Bring selected element to the top
|
||||
page.selected = selected;
|
||||
page.bringtotop(page.selected);
|
||||
}
|
||||
|
||||
// Select the element
|
||||
page.widgetselect(page.selected, true, wvalue, wdelete);
|
||||
|
||||
// Trigger widget select event
|
||||
page.onwidgetselect(page.selected);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle field on change events.
|
||||
*/
|
||||
wname.onchange = wname.onblur = function() {
|
||||
wvalue.onchange = wvalue.onblur = function() {
|
||||
if (page.selected == null)
|
||||
return false;
|
||||
page.selected.id = wname.value;
|
||||
|
||||
// Trigger page change event
|
||||
page.onpagechange(true);
|
||||
return false;
|
||||
};
|
||||
|
||||
wtext.onchange = wtext.onblur = function() {
|
||||
if (page.selected == null)
|
||||
return false;
|
||||
page.settext(page.selected, wtext.value);
|
||||
page.settext(page.selected, wvalue.value);
|
||||
page.selected.cover.style.width = ui.pixpos(page.selected.clientWidth + 4);
|
||||
page.selected.cover.style.height = ui.pixpos(page.selected.clientHeight + 4);
|
||||
|
||||
// Trigger page change event
|
||||
page.onpagechange(true);
|
||||
|
@ -246,19 +226,16 @@ page.edit = function(elem, wname, wtext, wadd, wdelete, onchange, onselect) {
|
|||
if (page.selected == null)
|
||||
return false;
|
||||
|
||||
// Reset current selection
|
||||
page.widgetselect(page.selected, false, wvalue, wdelete);
|
||||
|
||||
// Remove selected widget
|
||||
page.selected.parentNode.removeChild(page.selected);
|
||||
|
||||
// Reset current selection
|
||||
page.selected.cover.parentNode.removeChild(page.selected.cover);
|
||||
page.selected = null;
|
||||
wname.value = '';
|
||||
wname.disabled = true;
|
||||
wtext.value = '';
|
||||
wtext.disabled = true;
|
||||
wdelete.disabled = true;
|
||||
|
||||
// Trigger widget select event
|
||||
page.onwidgetselect('');
|
||||
page.onwidgetselect(null);
|
||||
|
||||
// Trigger page change event
|
||||
page.onpagechange(true);
|
||||
|
@ -276,6 +253,11 @@ page.edit = function(elem, wname, wtext, wadd, wdelete, onchange, onselect) {
|
|||
* Return the text of a widget.
|
||||
*/
|
||||
page.text = function(e) {
|
||||
var formula = e.id;
|
||||
if (formula.substring(0, 5) != 'page:') {
|
||||
return '=' + formula;
|
||||
}
|
||||
|
||||
if (e.className == 'h1' || e.className == 'h2' || e.className == 'text' || e.className == 'section')
|
||||
return car(childElements(e)).innerHTML;
|
||||
if (e.className == 'button' || e.className == 'checkbox')
|
||||
|
@ -331,6 +313,9 @@ page.hastext = function(e) {
|
|||
* Set the text of a widget.
|
||||
*/
|
||||
page.settext = function(e, t) {
|
||||
var formula = t.length > 1 && t.substring(0, 1) == '=';
|
||||
e.id = formula? t.substring(1) : 'page:' + e.className;
|
||||
|
||||
if (e.className == 'h1' || e.className == 'h2' || e.className == 'text' || e.className == 'section') {
|
||||
car(childElements(e)).innerHTML = t;
|
||||
return t;
|
||||
|
@ -351,10 +336,12 @@ page.settext = function(e, t) {
|
|||
return t;
|
||||
}
|
||||
if (e.className == 'list') {
|
||||
e.innerHTML = '<table class="datatable" style="width: 100%;;"><tr><td class="datatd">' + t + '</td></tr><tr><td class="datatd">...</td></tr></table>';
|
||||
return '';
|
||||
}
|
||||
if (e.className == 'table') {
|
||||
return '';
|
||||
e.innerHTML = '<table class="datatable" style="width: 100%;"><tr><td class="datatdl">' + t + '</td><td class="datatdr">...</td></tr><tr><td class="datatdl">...</td><td class="datatdr">...</td></tr></table>';
|
||||
return t;
|
||||
}
|
||||
if (e.className == 'link') {
|
||||
var l = t.split(',');
|
||||
|
@ -364,11 +351,11 @@ page.settext = function(e, t) {
|
|||
return t;
|
||||
}
|
||||
if (e.className == 'img') {
|
||||
car(childElements(e)).src = t;
|
||||
car(childElements(e)).src = formula? '/public/img.png' : t;
|
||||
return t;
|
||||
}
|
||||
if (e.className == 'iframe') {
|
||||
car(childElements(e)).href = t;
|
||||
car(childElements(e)).href = formula? '/public/iframe.html' : t;
|
||||
return t;
|
||||
}
|
||||
return '';
|
||||
|
@ -388,10 +375,12 @@ page.fixupwidget = function(e) {
|
|||
return e;
|
||||
}
|
||||
if (e.className == 'list') {
|
||||
e.style.width = '100%';
|
||||
car(childElements(e)).style.width = '100%';
|
||||
return e;
|
||||
}
|
||||
if (e.className == 'table') {
|
||||
e.style.width = '100%';
|
||||
car(childElements(e)).style.width = '100%';
|
||||
return e;
|
||||
}
|
||||
|
@ -426,6 +415,33 @@ page.bringtotop = function(n) {
|
|||
n.cover.parentNode.appendChild(n.cover);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw widget selection.
|
||||
*/
|
||||
page.widgetselect = function(n, s, wvalue, wdelete) {
|
||||
if (isNil(n) || !s) {
|
||||
// Clear the widget value field
|
||||
wvalue.value = '';
|
||||
wvalue.disabled = true;
|
||||
wdelete.disabled = true;
|
||||
|
||||
// Clear the widget outline
|
||||
if (!isNil(n))
|
||||
n.cover.style.borderWidth = '0px';
|
||||
}
|
||||
if (isNil(n))
|
||||
return true;
|
||||
|
||||
// Update the widget value field
|
||||
wvalue.value = page.text(n);
|
||||
wvalue.disabled = false;
|
||||
wdelete.disabled = false;
|
||||
|
||||
// Outline the widget
|
||||
n.cover.style.borderWidth = s? '2px' : '0px';
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Cover a page element with a <span> element to prevent
|
||||
* any input events to reach it.
|
||||
|
@ -433,13 +449,18 @@ page.bringtotop = function(n) {
|
|||
page.cover = function(e) {
|
||||
if (e.id == '' || isNil(e.style))
|
||||
return e;
|
||||
var cover = document.createElement('span');
|
||||
var cover = document.createElement('div');
|
||||
cover.style.position = 'absolute';
|
||||
cover.style.left = ui.pixpos(ui.numpos(e.style.left) - 5);
|
||||
cover.style.top = ui.pixpos(ui.numpos(e.style.top) - 5);
|
||||
cover.style.width = e.clientWidth + 10;
|
||||
cover.style.height = e.clientHeight + 10;
|
||||
cover.style.visibility = 'visible';
|
||||
cover.style.left = ui.pixpos(ui.numpos(e.style.left) - 2);
|
||||
cover.style.top = ui.pixpos(ui.numpos(e.style.top) - 2);
|
||||
cover.style.width = ui.pixpos(e.clientWidth + 4);
|
||||
cover.style.height = ui.pixpos(e.clientHeight + 4);
|
||||
cover.style.visibility = 'inherit';
|
||||
cover.style.borderStyle = 'solid';
|
||||
cover.style.borderWidth = '0px';
|
||||
cover.style.borderColor = '#598edd';
|
||||
cover.style.padding = '0px';
|
||||
cover.style.margin = '0px';
|
||||
cover.covered = e;
|
||||
e.cover = cover;
|
||||
e.parentNode.appendChild(cover);
|
||||
|
@ -458,11 +479,15 @@ page.clone = function(e) {
|
|||
var ne = document.createElement('span');
|
||||
|
||||
// Skip the palette: prefix
|
||||
ne.id = e.id.substr(8);
|
||||
ne.id = 'page:' + e.id.substr(8);
|
||||
|
||||
// Copy the class and HTML content
|
||||
ne.className = e.className;
|
||||
ne.innerHTML = e.innerHTML;
|
||||
|
||||
// Fixup the widget style
|
||||
page.fixupwidget(ne);
|
||||
|
||||
return ne;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,14 +36,18 @@
|
|||
|
||||
<table style="width: 100%;">
|
||||
<tr>
|
||||
<td><h1><span id="h1"></span><span id="appNameHeader"></span></h1></td>
|
||||
<td><h2><span id="h1"></span><span id="appNameHeader"></span></h2></td>
|
||||
<td style="vertical-align: middle; text-align: right;"><span id="saveStatus" style="font-weight: bold; color: #808080;">Saved</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table style="width: 100%;">
|
||||
<tr>
|
||||
<th class="thl thr" style="padding-top: 4px; padding-bottom: 4px;">Stats</th>
|
||||
<th class="thl thr" style="padding-top: 4px; padding-bottom: 4px; padding-left: 2px; padding-right: 2px; ">Stats</th>
|
||||
|
||||
<th class="thl thr" style="width: 100%; text-align: right; padding-right: 2px; padding-top: 0px; padding-bottom: 0px;">
|
||||
<input type="button" class="greenbutton" style="font-weight: bold; margin-top: 0px; margin-bottom: 0px; height: 24px;" id="cloneApp" value="Clone" title="Clone this app"/>
|
||||
</th>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
@ -85,8 +89,11 @@ function applink(appname) {
|
|||
|
||||
// Set page titles
|
||||
document.title = windowtitle(window.location.hostname) + ' - Stats - ' + appname;
|
||||
$('h1').innerHTML = hometitle(window.location.hostname);
|
||||
$('appNameHeader').innerHTML = ' - <a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '</a>';
|
||||
//$('h1').innerHTML = hometitle(window.location.hostname);
|
||||
$('appNameHeader').innerHTML = '<a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '.' + window.location.hostname + '</a>';
|
||||
var tclone = isNil(config.clone)? 'Clone' : config.clone;
|
||||
$('cloneApp').value = tclone;
|
||||
$('cloneApp').title = tclone + ' this app';
|
||||
|
||||
// Load the menu bar
|
||||
displaymenu();
|
||||
|
@ -96,7 +103,7 @@ ui.showbody();
|
|||
|
||||
// Init service references
|
||||
var editWidget = sca.component("EditWidget");
|
||||
var dashboard = sca.reference(editWidget, "dashboard");
|
||||
var dashboards = sca.reference(editWidget, "dashboards");
|
||||
|
||||
/**
|
||||
* The current app entry and corresponding saved XML content.
|
||||
|
@ -110,7 +117,7 @@ var savedappentryxml = '';
|
|||
function getapp(name) {
|
||||
if (isNil(name))
|
||||
return false;
|
||||
return dashboard.get(name, function(doc) {
|
||||
return dashboards.get(name, function(doc) {
|
||||
appentry = doc != null? car(elementsToValues(atom.readATOMEntry(mklist(doc)))) : mklist("'entry", mklist("'title", ''), mklist("'id", name));
|
||||
var title = cadr(assoc("'title", cdr(appentry)));
|
||||
$('appTitle').value = title;
|
||||
|
@ -127,7 +134,7 @@ function getapp(name) {
|
|||
function save(entryxml) {
|
||||
$('saveStatus').innerHTML = 'Saving';
|
||||
savedappentryxml = entryxml;
|
||||
dashboard.put(appname, savedappentryxml);
|
||||
dashboards.put(appname, savedappentryxml);
|
||||
$('saveStatus').innerHTML = 'Saved';
|
||||
return true;
|
||||
}
|
||||
|
@ -156,6 +163,13 @@ $('appForm').onsubmit = function() {
|
|||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle Clone button event.
|
||||
*/
|
||||
$('cloneApp').onclick = function() {
|
||||
return window.open('/clone/?app=' + appname, '_self');
|
||||
}
|
||||
|
||||
// Get the current app
|
||||
getapp(appname);
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ ui.showbody();
|
|||
*/
|
||||
var editWidget = sca.component("EditWidget");
|
||||
var store = sca.reference(editWidget, "store");
|
||||
var dashboard = sca.reference(editWidget, "dashboard");
|
||||
var dashboards = sca.reference(editWidget, "dashboards");
|
||||
|
||||
/**
|
||||
* Return the link to an app.
|
||||
|
@ -116,6 +116,13 @@ function editApp(appname) {
|
|||
return window.open('/page/?app=' + appname, '_self');
|
||||
}
|
||||
|
||||
/**
|
||||
* View an app.
|
||||
*/
|
||||
function viewApp(appname) {
|
||||
return window.open('/stats/?app=' + appname, '_self');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an app.
|
||||
*/
|
||||
|
@ -125,13 +132,6 @@ if (category == 'myapps') {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone an app.
|
||||
*/
|
||||
function cloneApp(appname) {
|
||||
return window.open('/clone/?app=' + appname, '_self');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and display list of apps.
|
||||
*/
|
||||
|
@ -150,10 +150,7 @@ function getapps(category) {
|
|||
apps += '<div class="box" style="width: 285px; display: inline-block; border: 1px; border-style: solid; border-color: #dcdcdc; border-collapse: collapse; margin: 5px; padding: 10px; vertical-align: top;">'
|
||||
apps += '<table><tr>';
|
||||
apps += '<td>';
|
||||
apps += '<div>' + ui.ahref(applink(name), '_blank', '<img src="/public/app.png" width="50" height="50" style="height: 50px; width: 50px; vertical-align: top; margin-right: 10px; margin-bottom: 5px;"></img>') + '</div>';
|
||||
apps += '<div><input type="button" class="greenbutton" id="cloneApp" value="' + clone + '" title="' + clone + ' this app" onclick="cloneApp(\'' + name + '\');"></div>';
|
||||
if (category == 'myapps')
|
||||
apps += '<div><input type="button" id="editApp" class="bluebutton" value="Edit" title="Edit this app" onclick="editApp(\'' + name + '\');"></div>';
|
||||
apps += '<div>' + ui.ahref('/stats/?app=' + name, '_self', '<img src="/public/app.png" width="50" height="50" style="height: 50px; width: 50px; vertical-align: top; margin-right: 10px; margin-bottom: 5px;"></img>') + '</div>';
|
||||
apps += '</td>';
|
||||
apps += '<td class="tdw">';
|
||||
apps += '<div style="font-weight: bold">' + ui.ahref(applink(name), '_blank', name) + '</div>';
|
||||
|
@ -164,7 +161,6 @@ function getapps(category) {
|
|||
apps += '<div>Feb 4, 2011</div>';
|
||||
apps += '<br/>';
|
||||
apps += '<div>' + title + '</div>';
|
||||
apps += '<br/>';
|
||||
apps += '</td>';
|
||||
apps += '</tr></table>';
|
||||
apps += '</div>';
|
||||
|
@ -174,7 +170,7 @@ function getapps(category) {
|
|||
}
|
||||
|
||||
if (category == 'myapps')
|
||||
return dashboard.get('', display);
|
||||
return dashboards.get('', display);
|
||||
return store.get(category, display);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue