You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by js...@apache.org on 2011/05/02 07:58:27 UTC
svn commit: r1098489 [1/3] - in /tuscany/sca-cpp/trunk: ./ modules/edit/
modules/edit/htdocs/ modules/edit/htdocs/app/ modules/edit/htdocs/clone/
modules/edit/htdocs/create/ modules/edit/htdocs/dash/
modules/edit/htdocs/data/ modules/edit/htdocs/graph/...
Author: jsdelfino
Date: Mon May 2 05:58:26 2011
New Revision: 1098489
URL: http://svn.apache.org/viewvc?rev=1098489&view=rev
Log:
Simplify HTML and Javascript to improve UI and performance on iOS devices. Fix offline cache manifest. Add an app clone page.
Added:
tuscany/sca-cpp/trunk/modules/edit/htdocs/clone/
tuscany/sca-cpp/trunk/modules/edit/htdocs/clone/index.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/create/
tuscany/sca-cpp/trunk/modules/edit/htdocs/create/index.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/menu.js
tuscany/sca-cpp/trunk/modules/edit/htdocs/public/delete.png
tuscany/sca-cpp/trunk/modules/edit/htdocs/public/delete.xcf
tuscany/sca-cpp/trunk/modules/edit/htdocs/stats/
tuscany/sca-cpp/trunk/modules/edit/htdocs/stats/index.html
tuscany/sca-cpp/trunk/modules/js/htdocs/all-min.js
tuscany/sca-cpp/trunk/modules/js/htdocs/ui-min.css
Removed:
tuscany/sca-cpp/trunk/modules/edit/htdocs/dash/
tuscany/sca-cpp/trunk/modules/edit/htdocs/graph/graph.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/main.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/menu.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/page/page.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/props/
tuscany/sca-cpp/trunk/modules/edit/htdocs/store/store.html
Modified:
tuscany/sca-cpp/trunk/.gitignore
tuscany/sca-cpp/trunk/modules/edit/Makefile.am
tuscany/sca-cpp/trunk/modules/edit/htdocs/app/cache-manifest.cmf
tuscany/sca-cpp/trunk/modules/edit/htdocs/app/index.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/cache-manifest.cmf
tuscany/sca-cpp/trunk/modules/edit/htdocs/data/index.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js
tuscany/sca-cpp/trunk/modules/edit/htdocs/graph/index.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/index.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/login/index.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/logout/index.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/page/index.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/page/page.js
tuscany/sca-cpp/trunk/modules/edit/htdocs/public/iframe.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/public/notauth.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/public/notfound.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/public/notyet.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/public/oops.html
tuscany/sca-cpp/trunk/modules/edit/htdocs/store/index.html
tuscany/sca-cpp/trunk/modules/edit/mkapplinks
tuscany/sca-cpp/trunk/modules/edit/ssl-start
tuscany/sca-cpp/trunk/modules/edit/start
tuscany/sca-cpp/trunk/modules/js/Makefile.am
tuscany/sca-cpp/trunk/modules/js/htdocs/ui.css
tuscany/sca-cpp/trunk/modules/js/htdocs/ui.js
tuscany/sca-cpp/trunk/modules/js/htdocs/uicyan.css
tuscany/sca-cpp/trunk/modules/server/server-conf
Modified: tuscany/sca-cpp/trunk/.gitignore
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/.gitignore?rev=1098489&r1=1098488&r2=1098489&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/.gitignore (original)
+++ tuscany/sca-cpp/trunk/.gitignore Mon May 2 05:58:26 2011
@@ -56,6 +56,7 @@ config.guess
config.sub
config.status
config.js
+all.js
depcomp
install-sh
ltmain.sh
@@ -85,6 +86,8 @@ doxygen
*.stamp
*.jar
*.prefix
+*.crt
+*.patch
index.yaml
core
gen-cpp/
@@ -133,7 +136,6 @@ json-value
value-json
element-value
value-element
-modules/edit/apps/*/htdocs
modules/edit/apps/*/nuvem
modules/edit/apps/*/lib
chat-send
Modified: tuscany/sca-cpp/trunk/modules/edit/Makefile.am
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/edit/Makefile.am?rev=1098489&r1=1098488&r2=1098489&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/edit/Makefile.am (original)
+++ tuscany/sca-cpp/trunk/modules/edit/Makefile.am Mon May 2 05:58:26 2011
@@ -20,7 +20,7 @@ if WANT_PYTHON
moddir = $(prefix)/modules/edit
dist_mod_SCRIPTS = start stop ssl-start mkapplinks
-nobase_dist_mod_DATA = edit.composite *.py htdocs/*.html htdocs/dash/*.html htdocs/data/*.html htdocs/app/*.html htdocs/store/*.html htdocs/props/*.html htdocs/graph/*.html htdocs/graph/*.js htdocs/page/*.html htdocs/page/*.js htdocs/login/*.html htdocs/logout/*.html palettes/*/palette.composite apps/*/app.composite apps/*/app.html dashboards/* store/*
-EXTRA_DIST = edit.composite *.py htdocs/*.html htdocs/dash/*.html htdocs/data/*.html htdocs/app/*.html htdocs/store/*.html htdocs/props/*.html htdocs/graph/*.html htdocs/graph/*.js htdocs/page/*.html htdocs/page/*.js htdocs/login/*.html htdocs/logout/*.html palettes/*/palette.composite apps/*/app.composite apps/*/app.html dashboards/* store/*
+nobase_dist_mod_DATA = edit.composite *.py htdocs/*.html htdocs/*.js htdocs/create/*.html htdocs/data/*.html htdocs/app/*.html htdocs/store/*.html htdocs/stats/*.html htdocs/graph/*.html htdocs/graph/*.js htdocs/page/*.html htdocs/page/*.js htdocs/login/*.html htdocs/logout/*.html palettes/*/palette.composite apps/*/app.composite apps/*/htdocs/app.html dashboards/* store/*
+EXTRA_DIST = edit.composite *.py htdocs/*.html htdocs/*.js htdocs/create/*.html htdocs/data/*.html htdocs/app/*.html htdocs/store/*.html htdocs/stats/*.html htdocs/graph/*.html htdocs/graph/*.js htdocs/page/*.html htdocs/page/*.js htdocs/login/*.html htdocs/logout/*.html palettes/*/palette.composite apps/*/app.composite apps/*/htdocs/app.html dashboards/* store/*
endif
Modified: tuscany/sca-cpp/trunk/modules/edit/htdocs/app/cache-manifest.cmf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/edit/htdocs/app/cache-manifest.cmf?rev=1098489&r1=1098488&r2=1098489&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/edit/htdocs/app/cache-manifest.cmf (original)
+++ tuscany/sca-cpp/trunk/modules/edit/htdocs/app/cache-manifest.cmf Mon May 2 05:58:26 2011
@@ -1,26 +1,16 @@
-CACHE-MANIFEST
+CACHE MANIFEST
# Common resources
-atomutil.js
-component.js
-elemutil.js
-jsconfig.js
-jsonutil.js
-scdl.js
-ui.css
-ui.js
-util.js
-xmlutil.js
+all-min.js
+config.js
+ui-min.css
# App resources
app.html
data/index.html
-index.html
favicon.ico
-login/index.html
-logout/index.html
+index.html
public/app.png
-public/grid72.png
public/iframe.html
public/img.png
public/notauth.html
@@ -30,3 +20,6 @@ public/oops.html
public/touchicon.png
robots.txt
+NETWORK:
+*
+
Modified: tuscany/sca-cpp/trunk/modules/edit/htdocs/app/index.html
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/edit/htdocs/app/index.html?rev=1098489&r1=1098488&r2=1098489&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/edit/htdocs/app/index.html (original)
+++ tuscany/sca-cpp/trunk/modules/edit/htdocs/app/index.html Mon May 2 05:58:26 2011
@@ -1,3 +1,4 @@
+<!DOCTYPE html>
<!--
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -16,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
-->
-<html manifest="cache-manifest.cmf">
+<html manifest="/cache-manifest.cmf">
<head>
<title>App</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/>
@@ -26,20 +27,13 @@
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"/>
+<link rel="stylesheet" type="text/css" href="/ui-min.css"/>
<script type="text/javascript" src="/config.js"></script>
-<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>
+<script type="text/javascript" src="/all-min.js"></script>
</head>
-<body class="delayed">
+<body class="delayed" onorientationchange="ui.reload();">
-<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;">
+<div id="bodydiv" class="devicewidth">
<div id="app"></div>
@@ -51,11 +45,11 @@ document.title = window.location.hostnam
if (ui.isIE()) $('bodydiv').style.right = -20;
/**
- * Page, every and location components.
+ * Start, stop, timer and geolocation components.
*/
-var appstartcomp = sca.httpclient('appstart', '/appstart');
-var appstopcomp = sca.httpclient('appstop', '/appstop');
-var everycomp = sca.httpclient('every', '/every');
+var startcomp = sca.httpclient('start', '/start');
+var stopcomp = sca.httpclient('stop', '/stop');
+var timercomp = sca.httpclient('timer', '/timer');
var geolocationcomp = sca.httpclient('geolocation', '/geolocation');
/**
@@ -255,11 +249,13 @@ function fixupwidget(e) {
}
if (e.className == 'list') {
car(childElements(e)).innerHTML = '';
+ e.style.width = '100%';
car(childElements(e)).style.width = '100%';
return e;
}
if (e.className == 'table') {
car(childElements(e)).innerHTML = '';
+ e.style.width = '100%';
car(childElements(e)).style.width = '100%';
return e;
}
@@ -300,26 +296,24 @@ function getpagedata() {
}
// Get the component app data
- var doc = appstartcomp.get(window.location.search, function(doc) {
- try {
- $('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);
- geolocationcomp.get('setup', evalcompinit);
- return true;
+ var doc = startcomp.get(window.location.search);
+ try {
+ $('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)));
- } catch(e) {
- log('exception on appstartcomp.get()', e);
- }
- });
+ // 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'));
+ return true;
+
+ } catch(e) {
+ log('exception on startcomp.get()', e);
+ }
} catch(e) {
log('exception in getpagedata()', e);
}
@@ -330,10 +324,7 @@ function getpagedata() {
* Get app data from a component.
*/
function getcompdata(comp, qs) {
- var doc = comp.get(qs, function(doc) {
- return displaydoc(doc);
- });
- return true;
+ return displaydoc(comp.get(qs));
}
/**
@@ -377,7 +368,7 @@ function buttonClickHandler(id) {
*/
function intervalHandler() {
try {
- return getcompdata(everycomp, compquery());
+ return getcompdata(timercomp, compquery());
} catch(e) {
log('exception in intervalHandler()', e);
}
Modified: tuscany/sca-cpp/trunk/modules/edit/htdocs/cache-manifest.cmf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/edit/htdocs/cache-manifest.cmf?rev=1098489&r1=1098488&r2=1098489&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/edit/htdocs/cache-manifest.cmf (original)
+++ tuscany/sca-cpp/trunk/modules/edit/htdocs/cache-manifest.cmf Mon May 2 05:58:26 2011
@@ -1,37 +1,24 @@
-CACHE-MANIFEST
+CACHE MANIFEST
# Common resources
-atomutil.js
-component.js
-elemutil.js
-jsconfig.js
-jsonutil.js
-scdl.js
-ui.css
-ui.js
-util.js
-xmlutil.js
+all-min.js
+config.js
+ui-min.css
# App resources
app/index.html
-dash/dashboard.html
-dash/index.html
+clone/index.html
+data/index.html
+create/index.html
data/index.html
favicon.ico
-graph/graph.html
graph/graph.js
graph/index.html
home.png
index.html
-login/index.html
-logout/index.html
-main.html
-menu.html
+menu.js
page/index.html
-page/page.html
page/page.js
-props/index.html
-props/props.html
public/app.png
public/grid72.png
public/iframe.html
@@ -42,6 +29,9 @@ public/notyet.html
public/oops.html
public/touchicon.png
robots.txt
+stats/index.html
store/index.html
-store/store.html
+
+NETWORK:
+*
Added: tuscany/sca-cpp/trunk/modules/edit/htdocs/clone/index.html
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/edit/htdocs/clone/index.html?rev=1098489&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/edit/htdocs/clone/index.html (added)
+++ tuscany/sca-cpp/trunk/modules/edit/htdocs/clone/index.html Mon May 2 05:58:26 2011
@@ -0,0 +1,163 @@
+<!DOCTYPE html>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<html>
+<head>
+<title></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"/>
+<link rel="apple-touch-icon" href="/public/touchicon.png"/>
+<link rel="stylesheet" type="text/css" href="/ui-min.css"/>
+<script type="text/javascript" src="/config.js"></script>
+<script type="text/javascript" src="/all-min.js"></script>
+<script type="text/javascript" src="/menu.js"></script>
+</head>
+<body class="delayed" onorientationchange="ui.reload();">
+<div id="bodydiv" class="devicewidth">
+
+<div id="menu"></div>
+
+<table style="width: 100%;">
+<tr>
+<td><h1><span id="h1"></span><span id="appNameHeader"></span></h1></td>
+</tr>
+</table>
+
+<table style="width: 100%;">
+<tr>
+<th id="th" class="thl thr" style="padding-top: 4px; padding-bottom:4px;">Clone this App</th>
+</tr>
+</table>
+
+<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><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>
+<tr><td><input type="checkbox" value="shared"/><span>Shared</span></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>App Title:</b></td></tr>
+<tr><td><input type="text" id="appTitle" size="30" placeholder="Enter the title of your app" style="width: 300px;"/></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>Description:</b></td></tr>
+<tr><td><textarea id="appDescription" cols="40" rows="3" placeholder="Enter a short description of your app" style="width: 300px;"></textarea></td></tr>
+<tr><td>
+<input id="cloneAppOKButton" type="submit" class="greenbutton" style="font-weight: bold;" value="Clone" title="Clone the app"/>
+<input id="cloneAppCancelButton" type="button" class="redbutton" value="Cancel"/>
+</td></tr>
+</table>
+</form>
+
+</div>
+
+<script type="text/javascript">
+// Get the app name
+var appname = ui.queryParams()['app'];
+if (isNil(appname))
+ window.open('/', '_self');
+
+/**
+ * Return the link to an app.
+ */
+function applink(appname) {
+ var protocol = window.location.protocol;
+ var host = window.location.hostname;
+ var port = ':' + window.location.port;
+ if (port == ':80' || port == ':443' || port == ':')
+ port = '';
+ var link = protocol + '//' + appname + '.' + host + port + '/';
+ return link;
+}
+
+// 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>';
+$('th').innerHTML = tclone + ' this App';
+$('cloneAppOKButton').value = tclone;
+$('cloneAppOKButton').title = tclone + ' the app';
+
+// Load the menu bar
+displaymenu();
+
+// Init form
+$('appDomain').innerHTML = '.' + window.location.hostname;
+
+// Show the page
+ui.showbody();
+
+// Init service references
+var editWidget = sca.component("EditWidget");
+var dashboard = sca.reference(editWidget, "dashboard");
+var apps = sca.reference(editWidget, "apps");
+
+/**
+ * The current app entry and corresponding saved XML content.
+ */
+var appentry;
+var savedappentryxml = '';
+
+/**
+ * Get and display an app.
+ */
+function getapp(name) {
+ if (isNil(name))
+ return false;
+ return apps.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;
+ $('appDescription').innerHTML = '';
+ savedappentryxml = car(atom.writeATOMEntry(valuesToElements(mklist(appentry))));
+ return true;
+ });
+}
+
+/**
+ * Clone an app.
+ */
+$('cloneAppForm').onsubmit = function() {
+ var name = $('appName').value;
+ if (name == '')
+ return false;
+ 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');
+ return false;
+};
+
+/**
+ * Cancel cloning an app.
+ */
+$('cloneAppCancelButton').onclick = function() {
+ return window.open('/store/', '_self');
+};
+
+// Get the current app
+getapp(appname);
+
+</script>
+
+</body>
+</html>
+
Added: tuscany/sca-cpp/trunk/modules/edit/htdocs/create/index.html
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/edit/htdocs/create/index.html?rev=1098489&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/edit/htdocs/create/index.html (added)
+++ tuscany/sca-cpp/trunk/modules/edit/htdocs/create/index.html Mon May 2 05:58:26 2011
@@ -0,0 +1,112 @@
+<!DOCTYPE html>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<html>
+<head>
+<title>Create 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"/>
+<link rel="apple-touch-icon" href="/public/touchicon.png"/>
+<link rel="stylesheet" type="text/css" href="/ui-min.css"/>
+<script type="text/javascript" src="/config.js"></script>
+<script type="text/javascript" src="/all-min.js"></script>
+<script type="text/javascript" src="/menu.js"></script>
+</head>
+<body class="delayed" onorientationchange="ui.reload();">
+<div id="bodydiv" class="devicewidth">
+
+<div id="menu"></div>
+
+<table style="width: 100%;">
+<tr><td><h1><span id="h1"></span></h1></td></tr>
+</table>
+
+<table style="width: 100%;">
+<tr>
+<th class="thl thr" style="padding-top: 4px; padding-bottom:4px;">Create an App</th>
+</tr>
+</table>
+
+<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><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>
+<tr><td><input type="checkbox" value="shared"/><span>Shared</span></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>App Title:</b></td></tr>
+<tr><td><input type="text" id="appTitle" size="30" placeholder="Enter the title of your app" style="width: 300px;"/></td></tr>
+<tr><tr><td style="padding-top: 6px;"><b>Description:</b></td></tr>
+<tr><td><textarea id="appDescription" cols="40" rows="3" placeholder="Enter a short description of your app" style="width: 300px;"></textarea></td></tr>
+<tr><td>
+<input id="createAppOKButton" type="submit" class="greenbutton" style="font-weight: bold;" value="Create" title="Create the app"/>
+<input id="createAppCancelButton" type="button" class="redbutton" value="Cancel"/>
+</td></tr>
+</table>
+</form>
+
+</div>
+
+<script type="text/javascript">
+// Set page titles
+document.title = windowtitle(window.location.hostname) + ' - Create App';
+$('h1').innerHTML = hometitle(window.location.hostname);
+
+// Load the menu bar
+displaymenu();
+
+// Init form
+$('appDomain').innerHTML = '.' + window.location.hostname;
+
+// Show the page
+ui.showbody();
+
+// Init service references
+var editWidget = sca.component("EditWidget");
+var dashboard = sca.reference(editWidget, "dashboard");
+
+/**
+ * Create an app.
+ */
+$('createAppForm').onsubmit = function() {
+ var name = $('appName').value;
+ if (name == '')
+ return false;
+ var title = $('appTitle').value;
+ var app = mklist(mklist("'entry", mklist("'title", title != ''? title : name), mklist("'id", name)));
+ var entry = atom.writeATOMEntry(valuesToElements(app));
+ dashboard.put(name, car(entry));
+ window.open('/store/', '_self');
+ return false;
+};
+
+/**
+ * Cancel creating an app.
+ */
+$('createAppCancelButton').onclick = function() {
+ return window.open('/store/', '_self');
+};
+
+</script>
+
+</body>
+</html>
+
Modified: tuscany/sca-cpp/trunk/modules/edit/htdocs/data/index.html
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/edit/htdocs/data/index.html?rev=1098489&r1=1098488&r2=1098489&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/edit/htdocs/data/index.html (original)
+++ tuscany/sca-cpp/trunk/modules/edit/htdocs/data/index.html Mon May 2 05:58:26 2011
@@ -1,3 +1,4 @@
+<!DOCTYPE html>
<!--
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -27,18 +28,11 @@ document.title = 'View - ' + window.loca
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
<link rel="apple-touch-icon" href="/public/touchicon.png"/>
-<link rel="stylesheet" type="text/css" href="/ui.css">
+<link rel="stylesheet" type="text/css" href="/ui-min.css">
<script type="text/javascript" src="/config.js"></script>
-<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>
+<script type="text/javascript" src="/all-min.js"></script>
</head>
-<body class="delayed">
+<body class="delayed" onorientationchange="ui.reload();">
<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;">
@@ -75,15 +69,14 @@ function datatable(e) {
*/
function mkdoctable(doc) {
var tr = '<tr><td class="datatdl">' + 'value' + '</td>' + '<td class="datatdr">' + doc + '</td></tr>';
- return '<table class="datatable ' + (window.name == 'dataFrame'? ' databg' : '') + '" style="width: 100%;">' + tr + '</table>';
+ return '<table class="datatable ' + (window.name == 'previewFrame'? ' databg' : '') + '" style="width: 100%;">' + tr + '</table>';
}
/**
* Get and display the contents of the current component.
*/
function getdata() {
- comp.get('', function(doc) {
-
+ return comp.get('', function(doc) {
if (json.isJSON(mklist(doc)))
return display(datatable(json.readJSON(mklist(doc))));
Modified: tuscany/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js?rev=1098489&r1=1098488&r2=1098489&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js (original)
+++ tuscany/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js Mon May 2 05:58:26 2011
@@ -53,15 +53,15 @@ graph.colors.lightgray1 = '#dcdcdc'
/**
* Default positions and sizes.
*/
-var palcx = 250;
-var trashcx = 230;
+var palcx = 2500;
+var trashcx = 2480;
var proxcx = 20;
var proxcy = 20;
var buttoncx = 65;
var buttoncy = 30;
var curvsz = 6;
var tabsz = 2;
-var fontsz = '';
+var fontsz = '11px';
/**
* Base path class.
@@ -103,986 +103,520 @@ graph.BasePath = function() {
};
/**
- * Rendering functions that work both with VML and SVG.
+ * SVG rendering functions.
*/
+graph.svgns='http://www.w3.org/2000/svg';
+
/**
- * VML rendering.
+ * Make an SVG graph.
*/
-if (ui.isIE()) {
+graph.mkgraph = function(pos, cvalue, cadd, cdelete) {
+
+ // Create a div element to host the graph
+ var div = document.createElement('div');
+ div.id = 'svgdiv';
+ div.style.position = 'absolute';
+ div.style.left = ui.pixpos(pos.xpos());
+ div.style.top = ui.pixpos(pos.ypos());
+ div.style.overflow = 'hidden';
+ document.body.appendChild(div);
+
+ // Create SVG element
+ var svg = document.createElementNS(graph.svgns, 'svg');
+ svg.style.height = ui.pixpos(5000);
+ svg.style.width = ui.pixpos(5000);
+ div.appendChild(svg);
- graph.vmlns='urn:schemas-microsoft-com:vml';
- document.write('<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />');
+ // Track element dragging and selection
+ graph.dragging = null;
+ graph.selected = null;
+ cvalue.disabled = true;
+ cdelete.disabled = true;
/**
- * Make a VML graph.
+ * Find the first draggable element in a hierarchy of elements.
*/
- graph.mkgraph = function(pos, cname, pvalue) {
+ function draggable(n) {
+ if (n == div || n == svg || n == null)
+ return null;
+ if (n.nodeName == 'g' && !isNil(n.id) && n.id != '')
+ return n;
+ return draggable(n.parentNode);
+ }
- // Create div element to host the graph
- var div = document.createElement('div');
- div.id = 'vmldiv';
- div.style.position = 'absolute';
- div.style.left = pos.xpos();
- div.style.top = pos.ypos();
- document.body.appendChild(div);
-
- // Create a VML group
- var vmlg = document.createElement('v:group');
- vmlg.style.width = 5000;
- vmlg.style.height = 5000;
- vmlg.coordsize = '5000,5000';
- div.appendChild(vmlg);
+ /**
+ * Handle a mouse down event.
+ */
+ div.onmousedown = function(e) {
- // Track element dragging and selection
- graph.dragging = null;
- graph.selected = null;
- cname.disabled = true;
- pvalue.disabled = true;
+ // 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;
- /**
- * Find the first draggable element in a hierarchy of elements.
- */
- function draggable(n) {
- if (n == vmlg)
- return null;
- if (n.nodeName == 'group' && n.id != '')
- return n;
- return draggable(n.parentNode);
+ // Trigger component select event
+ svg.oncompselect('');
+ return true;
}
- /**
- * Handle a mousedown event.
- */
- vmlg.onmousedown = function() {
- window.event.returnValue = false;
-
- // Find draggable element
- graph.dragging = draggable(window.event.srcElement);
+ // 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;
- if (graph.dragging == null) {
-
- // Reset current selection
- cname.value = '';
- cname.disabled = true;
- pvalue.value = '';
- pvalue.disabled = true;
-
- // Trigger component select event
- vmlg.oncompselect('');
- return false;
- }
-
- // Clone component from the palette
- var compos = scdl.composite(vmlg.compos);
- if (graph.dragging.id.substring(0, 8) == 'palette:') {
- graph.dragging = graph.clonepalette(graph.dragging, compos);
- graph.selected = graph.dragging;
- }
-
- // Cut wire to component
- if (graph.dragging.parentNode != vmlg)
- setElement(compos, graph.cutwire(graph.dragging, compos, vmlg));
-
- // Bring component to the top
- graph.bringtotop(graph.dragging, vmlg);
-
- // Remember mouse position
- graph.dragX = window.event.clientX;
- graph.dragY = window.event.clientY;
- vmlg.setCapture();
-
- // Update the component name and property value fields
- cname.value = graph.selected.id;
- cname.disabled = false;
- pvalue.value = graph.property(graph.selected.comp);
- pvalue.disabled = !graph.hasproperty(graph.selected.comp);
-
- // Trigger component select event
- vmlg.oncompselect(vmlg.appname, graph.selected.id);
- return false;
- };
-
- /**
- * Handle a mouseup event.
- */
- vmlg.onmouseup = function() {
- if (graph.dragging == null)
- return false;
-
- if (graph.dragging.parentNode == vmlg && 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(vmlg.compos);
- setElement(compos, graph.addcomp(graph.dragging.comp, compos));
- graph.dragging.compos = vmlg.compos;
- }
-
- // Update component position
- setElement(graph.dragging.comp, graph.movecomp(graph.dragging.comp, graph.abspos(graph.dragging, vmlg)));
-
- // Wire component to neighboring reference
- if (!isNil(graph.dragging.svcpos)) {
- var compos = scdl.composite(vmlg.compos);
- setElement(compos, grah.clonerefs(graph.wire(graph.dragging, compos, vmlg)));
- }
-
- } else {
-
- // Discard component dragged out of composite
- vmlg.removeChild(graph.dragging);
- if (!isNil(graph.dragging.compos)) {
- var compos = scdl.composite(vmlg.compos);
- setElement(compos, graph.clonerefs(graph.gcollect(graph.removecomp(graph.dragging.comp, compos))));
- }
-
- // Reset current selection
- graph.selected = null;
- cname.value = '';
- cname.disabled = true;
- pvalue.value = '';
- pvalue.disabled = true;
-
- // Trigger component select event
- vmlg.oncompselect('');
- }
-
- // Trigger composite change event
- vmlg.oncomposchange(false);
- }
-
- // Forget current dragged component
- graph.dragging = null;
- vmlg.releaseCapture();
-
- // Refresh the composite
- graph.refresh(vmlg);
- return false;
- };
- /**
- * Handle a mousemove event.
- */
- vmlg.onmousemove = function() {
- if (graph.dragging == null)
- return false;
-
- // Calculate new position of dragged element
+ // Move into the editing area and hide the palette
var gpos = graph.relpos(graph.dragging);
- var newX = gpos.xpos() + (window.event.clientX - graph.dragX);
- var newY = gpos.ypos() + (window.event.clientY - graph.dragY);
- if (newX >= 0)
- graph.dragX = window.event.clientX;
- else
- newX = 0;
- if (newY >= 0)
- graph.dragY = window.event.clientY;
- else
- newY = 0;
+ graph.move(graph.dragging, graph.mkpath().move(gpos.xpos() + palcx, gpos.ypos()));
+ div.style.left = ui.pixpos(palcx * -1);
+ }
- // Move the dragged element
- graph.move(graph.dragging, graph.mkpath().move(newX, newY));
+ // 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);
+
+ // 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);
- return false;
- };
+ if (e.preventDefault)
+ e.preventDefault();
+ else
+ e.returnValue = false;
+ return true;
+ };
- /**
- * Handle field on change events.
- */
- cname.onchange = function() {
- if (graph.selected == null)
- return false;
-
- // Change component name and refactor references to it
- var compos = scdl.composite(vmlg.compos);
- cname.value = graph.ucid(cname.value, compos);
- cname.disabled = false;
- graph.selected.id = cname.value;
- setElement(compos, graph.renamecomp(graph.selected.comp, compos, cname.value));
+ // Support touch devices
+ div.ontouchstart = div.onmousedown;
- // Trigger component select event
- vmlg.oncompselect(vmlg.appname, graph.selected.id);
+ /**
+ * Handle a mouse up event.
+ */
+ div.onmouseup = function(e) {
+ if (graph.dragging == null)
+ return true;
- // Refresh the composite
- graph.refresh(vmlg);
+ if (graph.dragging.parentNode == svg && graph.dragging.id.substring(0, 8) != 'palette:') {
+ var gpos = graph.relpos(graph.dragging);
+ if (gpos.xpos() >= trashcx) {
- // Trigger composite change event
- vmlg.oncomposchange(true);
- return false;
- };
+ // 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;
+ }
- pvalue.onchange = function() {
- if (graph.selected == null)
- return false;
-
- // Change the component property value
- graph.setproperty(graph.selected.comp, pvalue.value);
- pvalue.value = graph.property(graph.selected.comp);
- pvalue.disabled = !graph.hasproperty(graph.selected.comp);
+ // Update component position
+ setElement(graph.dragging.comp, graph.movecomp(graph.dragging.comp, graph.abspos(graph.dragging, svg)));
- // Refresh the composite
- graph.refresh(vmlg);
+ // 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))));
+ }
- // Trigger composite change event
- vmlg.oncomposchange(true);
- return false;
- };
+ } else {
- // Create hidden spans to help compute the width of
- // component, reference and property titles
- graph.comptitlewidthdiv = document.createElement('span');
- graph.comptitlewidthdiv.style.visibility = 'hidden'
- if (fontsz != '')
- graph.comptitlewidthdiv.style.fontSize = fontsz;
- div.appendChild(graph.comptitlewidthdiv);
-
- graph.reftitlewidthdiv = document.createElement('span');
- graph.reftitlewidthdiv.style.visibility = 'hidden'
- if (fontsz != '')
- graph.comptitlewidthdiv.style.fontSize = fontsz;
- div.appendChild(graph.reftitlewidthdiv);
-
- graph.proptitlewidthdiv = document.createElement('span');
- graph.proptitlewidthdiv.style.visibility = 'hidden'
- if (fontsz != '')
- graph.comptitlewidthdiv.style.fontSize = fontsz;
- div.appendChild(graph.proptitlewidthdiv);
+ // 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)))));
+ }
- return vmlg;
- };
+ // Reset current selection
+ graph.selected = null;
+ cvalue.value = '';
+ cvalue.disabled = true;
+ cdelete.disabled = true;
- /**
- * Make a shape path.
- */
- graph.mkpath = function() {
- function Path() {
- this.BasePath = graph.BasePath;
- this.BasePath();
-
- this.clone = function() {
- return graph.mkpath().pos(this.xpos(), this.ypos());
- };
-
- this.move = function(x, y) {
- this.path += 'M ' + x + ',' + y + ' ';
- return this.pos(x, y);
- };
-
- this.line = function(x, y) {
- this.path += 'L ' + x + ',' + y + ' ';
- return this.pos(x, y);
- };
-
- this.curve = function(x1, y1, x, y) {
- this.path += 'QB ' + x1 + ',' + y1 + ',' + x + ',' + y + ' ';
- return this.pos(x, y);
- };
-
- this.end = function() {
- this.path += 'X E';
- return this;
- };
+ // Trigger component select event
+ svg.oncompselect('');
+ }
}
- return new Path();
- };
-
- /**
- * Return an element representing a title.
- */
- graph.mktitle = function(t, style, pos) {
- var title = document.createElement('v:textbox');
- title.style.position = 'absolute';
- title.style.left = pos.xpos() + 2;
- title.style.top = pos.ypos();
- title.inset = '' + 6 + 'px ' + pos.ypos() + 'px 0px 0px';
- if (style != '')
- title.style.cssText = style;
- if (fontsz != '')
- title.style.fontSize = fontsz;
- var tnode = document.createTextNode(t);
- title.appendChild(tnode);
- return title;
- };
-
- /**
- * Return an element representing the title of a component.
- */
- graph.comptitle = function(comp) {
- var tsvcs = graph.tsvcs(comp);
- var lsvcs = graph.lsvcs(comp);
- var pos = graph.mkpath().move(isNil(lsvcs)? tabsz : (tabsz * 5), isNil(tsvcs)? tabsz : (tabsz * 5));
- return graph.mktitle(graph.title(comp), graph.compstyle(comp), pos);
- };
-
- /**
- * Return the width of the title of a component.
- */
- graph.comptitlewidth = function(comp) {
- var t = graph.title(comp);
- graph.comptitlewidthdiv.innerHTML = t;
- var twidth = graph.comptitlewidthdiv.offsetWidth + 2;
- graph.comptitlewidthdiv.innerHTML = '';
- return twidth;
- };
-
- /**
- * Return an element representing the value of a property.
- */
- graph.proptitle = function(comp) {
- var tsvcs = graph.tsvcs(comp);
- var lsvcs = graph.lsvcs(comp);
- var pos = graph.mkpath().move(graph.comptitlewidth(comp) + 7 + (isNil(lsvcs)? tabsz : (tabsz * 5)), isNil(tsvcs)? tabsz : (tabsz * 5));
- return graph.mktitle(graph.propertytitle(comp), graph.propstyle(comp), pos);
- };
-
- /**
- * Return the width of the value of a property.
- */
- graph.proptitlewidth = function(comp) {
- var t = graph.proptitle(comp);
- graph.proptitlewidthdiv.innerHTML = t;
- var twidth = graph.proptitlewidthdiv.offsetWidth + 4;
- graph.proptitlewidthdiv.innerHTML = '';
- return twidth;
- };
+ // Forget current dragged component
+ graph.dragging = null;
- /**
- * Return an element representing the title of a reference.
- */
- graph.reftitle = function(ref) {
- return graph.mktitle(graph.title(ref), graph.refstyle(ref), graph.mkpath().move(25,25));
- };
+ // Refresh the composite
+ graph.refresh(svg);
- /**
- * Return the width of the title of a reference.
- */
- graph.reftitlewidth = function(ref) {
- var t = graph.title(ref);
- graph.reftitlewidthdiv.innerHTML = t;
- var twidth = graph.reftitlewidthdiv.offsetWidth;
- graph.reftitlewidthdiv.innerHTML = '';
- return twidth;
+ // Trigger composite change event
+ svg.oncomposchange(false);
+ return true;
};
- /**
- * Return a node representing a component.
- */
- graph.compnode = function(comp, cassoc, pos) {
+ // Support touch devices
+ div.ontouchend = div.onmouseup;
- // Make the component and property title elements
- var title = graph.comptitle(comp);
- var prop = graph.proptitle(comp);
-
- // Compute the component shape path
- var path = graph.comppath(comp, cassoc);
- var d = path.str();
-
- // Create the main component shape
- var shape = document.createElement('v:shape');
- shape.style.width = 5000;
- shape.style.height = 5000;
- shape.coordsize = '5000,5000';
- shape.path = d;
- shape.fillcolor = graph.color(comp);
- shape.stroked = 'false';
-
- // Create an overlay contour shape
- var contour = document.createElement('v:shape');
- contour.style.width = 5000;
- contour.style.height = 5000;
- contour.coordsize = '5000,5000';
- contour.path = d;
- contour.filled = 'false';
- contour.strokecolor = graph.colors.gray;
- contour.strokeweight = '1';
- contour.style.left = 1;
- contour.style.top = 1;
- var stroke = document.createElement('v:stroke');
- stroke.opacity = '20%';
- contour.appendChild(stroke);
-
- // Create a group and add the component and contour shapes to it
- var g = document.createElement('v:group');
- g.id = scdl.name(comp);
- g.style.width = 5000;
- g.style.height = 5000;
- g.coordsize = '5000,5000';
- g.style.left = pos.xpos();
- g.style.top = pos.ypos();
- g.appendChild(shape);
- shape.appendChild(title);
- shape.appendChild(prop);
- g.appendChild(contour)
-
- // Store the component and the positions of its services
- // and references in the component shape
- g.comp = comp;
- g.refpos = reverse(path.refpos);
- g.svcpos = reverse(path.svcpos);
+ // Handle a mouse click event.
+ div.onclick = function(e) {
+ if (graph.dragging == null && (e.target == div || e.target == svg)) {
- return g;
- };
-
- /**
- * Return a graphical group.
- */
- graph.mkgroup = function(pos) {
- var g = document.createElement('v:group');
- g.style.left = pos.xpos();
- g.style.top = pos.ypos();
- return g;
- };
+ // Dismiss the palette
+ if (ui.numpos(div.style.left) != (palcx * -1))
+ div.style.left = ui.pixpos(palcx * -1);
+ }
+ return true;
+ }
/**
- * Return a node representing a button.
+ * Handle a mouse move event.
*/
- graph.mkbutton = function(t, pos) {
-
- // Make the title element
- var title = graph.mktitle(t, '', graph.mkpath().move(4,4));
-
- // Compute the path of the button shape
- var path = graph.buttonpath().str();
+ window.onmousemove = function(e) {
+ if (graph.dragging == null)
+ return true;
- // Create the main button shape
- var shape = document.createElement('v:shape');
- shape.style.width = 5000;
- shape.style.height = 5000;
- shape.coordsize = '5000,5000';
- shape.path = path;
- shape.fillcolor = graph.colors.lightgray;
- shape.stroked = 'false';
-
- // Create an overlay contour shape
- var contour = document.createElement('v:shape');
- contour.style.width = 5000;
- contour.style.height = 5000;
- contour.coordsize = '5000,5000';
- contour.path = path;
- contour.filled = 'false';
- contour.strokecolor = graph.colors.gray;
- contour.strokeweight = '1';
- contour.style.left = 1;
- contour.style.top = 1;
- var stroke = document.createElement('v:stroke');
- stroke.opacity = '20%';
- contour.appendChild(stroke);
-
- // Create a group and add the button and contour shapes to it
- var g = document.createElement('v:group');
- g.style.width = 5000;
- g.style.height = 5000;
- g.coordsize = '5000,5000';
- g.style.left = pos.xpos();
- g.style.top = pos.ypos();
- g.appendChild(shape);
- shape.appendChild(title);
- g.appendChild(contour)
- return g;
- };
+ // 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)
+ graph.dragX = pos.screenX;
+ else
+ newX = 0;
+ if (newY >= 0)
+ graph.dragY = pos.screenY;
+ else
+ newY = 0;
- /**
- * Return the relative position of a node.
- */
- graph.relpos = function(e) {
- var curX = ui.csspos(e.style.left);
- var curY = ui.csspos(e.style.top);
- return graph.mkpath().move(curX, curY);
- };
+ // Move the dragged element
+ graph.move(graph.dragging, graph.mkpath().move(newX, newY));
- /**
- * Move a node.
- */
- graph.move = function(e, pos) {
- e.style.left = pos.xpos();
- e.style.top = pos.ypos();
+ return true;
};
-} else {
+ // Support touch devices
+ div.ontouchmove = window.onmousemove;
/**
- * SVG rendering.
+ * Handle field on change events.
*/
- graph.svgns='http://www.w3.org/2000/svg';
+ cvalue.onchange = function() {
+ if (graph.selected == null)
+ return false;
- /**
- * Make an SVG graph.
- */
- graph.mkgraph = function(pos, cname, pvalue) {
+ // Change component name and refactor references to it
+ function changename() {
+ var compos = scdl.composite(svg.compos);
+ cvalue.value = graph.ucid(cvalue.value, compos);
+ graph.selected.id = cvalue.value;
+ setElement(compos, graph.sortcompos(graph.renamecomp(graph.selected.comp, compos, cvalue.value)));
- // Create a div element to host the graph
- var div = document.createElement('div');
- div.id = 'svgdiv';
- div.style.position = 'absolute';
- div.style.left = pos.xpos();
- div.style.top = pos.ypos();
- // -webkit-user-select: none;
- document.body.appendChild(div);
-
- // Create SVG element
- var svg = document.createElementNS(graph.svgns, 'svg');
- svg.style.height = 5000;
- svg.style.width = 5000;
- div.appendChild(svg);
+ // Trigger component select event
+ svg.oncompselect(graph.selected.id);
- // Track element dragging and selection
- graph.dragging = null;
- graph.selected = null;
- cname.disabled = true;
- pvalue.disabled = true;
+ // Refresh the composite
+ graph.refresh(svg);
- /**
- * Find the first draggable element in a hierarchy of elements.
- */
- function draggable(n) {
- if (n == svg)
- return null;
- if (n.nodeName == 'g' && n.id != '')
- return n;
- return draggable(n.parentNode);
+ // Trigger composite change event
+ svg.oncomposchange(true);
+ return false;
}
- /**
- * Handle a mouse down event.
- */
- svg.onmousedown = function(e) {
- if (e.preventDefault)
- e.preventDefault();
- else
- e.returnValue = false;
-
- // Find draggable component
- graph.dragging = draggable(e.target);
- graph.selected = graph.dragging;
- if (graph.dragging == null) {
-
- // Reset current selection
- cname.value = '';
- cname.disabled = true;
- pvalue.value = '';
- pvalue.disabled = true;
+ // Change the component property value
+ function changeprop() {
+ graph.setproperty(graph.selected.comp, cvalue.value);
+ cvalue.value = graph.property(graph.selected.comp);
+ cvalue.disabled = !graph.hasproperty(graph.selected.comp);
- // Trigger component select event
- svg.oncompselect('');
- return false;
- }
-
- // 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;
- }
-
- // Cut wire to component
- if (graph.dragging.parentNode != svg)
- setElement(compos, graph.cutwire(graph.dragging, compos, svg));
-
- // Bring component to the top
- graph.bringtotop(graph.dragging, svg);
-
- // Remember current mouse position
- var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
- graph.dragX = pos.screenX;
- graph.dragY = pos.screenY;
+ // Refresh the composite
+ graph.refresh(svg);
- // Update the component name and property value fields
- cname.value = graph.selected.id;
- cname.disabled = false;
- pvalue.value = graph.property(graph.selected.comp);
- pvalue.disabled = !graph.hasproperty(graph.selected.comp);
-
- // Trigger component select event
- svg.oncompselect(svg.appname, graph.selected.id);
+ // Trigger composite change event
+ svg.oncomposchange(true);
return false;
- };
-
- // Support touch devices
- svg.ontouchstart = svg.onmousedown;
+ }
- /**
- * Handle a mouse up event.
- */
- window.onmouseup = function(e) {
- if (graph.dragging == null)
- return false;
-
- 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.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)));
-
- // Wire component to neighboring reference
- if (!isNil(graph.dragging.svcpos)) {
- var compos = scdl.composite(svg.compos);
- setElement(compos, 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.clonerefs(graph.gcollect(graph.removecomp(graph.dragging.comp, compos))));
- }
-
- // Reset current selection
- graph.selected = null;
- cname.value = '';
- cname.disabled = true;
- pvalue.value = '';
- pvalue.disabled = true;
+ return graph.hasproperty(graph.selected.comp)? changeprop() : changename();
+ };
+
+ // Handle delete event
+ cdelete.onclick = function() {
+ if (graph.selected == null)
+ return false;
+ if (graph.selected.id.substring(0, 8) != 'palette:' && !isNil(graph.selected.compos)) {
- // Trigger component select event
- svg.oncompselect('');
- }
- }
+ // Remove selected component
+ var compos = scdl.composite(svg.compos);
+ setElement(compos, graph.sortcompos(graph.clonerefs(graph.gcollect(graph.removecomp(graph.selected.comp, compos)))));
- // Forget current dragged component
- graph.dragging = null;
+ // Reset current selection
+ graph.selected = null;
+ cvalue.value = '';
+ cvalue.disabled = true;
+ cdelete.disabled = true;
// Refresh the composite
graph.refresh(svg);
- // Trigger composite change event
- svg.oncomposchange(false);
- return false;
- };
-
- // Support touch devices
- window.top.onmouseup = window.onmouseup;
- window.ontouchend = window.onmouseup;
- window.gestureend = window.onmouseup;
- window.top.gestureend = window.onmouseup;
- window.top.ontouchend = window.onmouseup;
- window.ontouchcancel = window.onmouseup;
- window.top.ontouchcancel = window.onmouseup;
-
- /**
- * Handle a mouse move event.
- */
- window.onmousemove = function(e) {
- if (graph.dragging == null)
- return false;
- if (e.preventDefault)
- e.preventDefault();
- else
- e.returnValue = false;
+ // Trigger component select event
+ svg.oncompselect('');
- // 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)
- graph.dragX = pos.screenX;
- else
- newX = 0;
- if (newY >= 0)
- graph.dragY = pos.screenY;
- else
- newY = 0;
+ // Trigger composite change event
+ svg.oncomposchange(true);
+ }
+ return false;
+ };
- // Move the dragged element
- graph.move(graph.dragging, graph.mkpath().move(newX, newY));
+ // Handle add event
+ cadd.onclick = function() {
- return false;
- };
+ // Show the palette
+ div.style.left = ui.pixpos(0);
+ return false;
+ };
- // Support touch devices
- window.top.onmousemove = window.onmousemove;
- window.ontouchmove = window.onmousemove;
- window.top.ontouchmove = window.onmousemove;
+ // Create a hidden SVG element to help compute the width
+ // of component and reference titles
+ graph.titlewidthsvg = document.createElementNS(graph.svgns, 'svg');
+ graph.titlewidthsvg.style.visibility = 'hidden';
+ graph.titlewidthsvg.style.height = ui.pixpos(0);
+ graph.titlewidthsvg.style.width = ui.pixpos(0);
+ div.appendChild(graph.titlewidthsvg);
- /**
- * Handle field on change events.
- */
- cname.onchange = function() {
- if (graph.selected == null)
- return false;
+ return svg;
+};
- // Change component name and refactor references to it
- var compos = scdl.composite(svg.compos);
- cname.value = graph.ucid(cname.value, compos);
- graph.selected.id = cname.value;
- setElement(compos, graph.renamecomp(graph.selected.comp, compos, cname.value));
+/**
+ * Make a path.
+ */
+graph.mkpath = function() {
+ function Path() {
+ this.BasePath = graph.BasePath;
+ this.BasePath();
- // Trigger component select event
- svg.oncompselect(svg.appname, graph.selected.id);
+ this.clone = function() {
+ return graph.mkpath().pos(this.xpos(), this.ypos());
+ };
- // Refresh the composite
- graph.refresh(svg);
+ this.move = function(x, y) {
+ this.path += 'M' + x + ',' + y + ' ';
+ return this.pos(x, y);
+ };
- // Trigger composite change event
- svg.oncomposchange(true);
- return false;
+ this.line = function(x, y) {
+ this.path += 'L' + x + ',' + y + ' ';
+ return this.pos(x, y);
};
-
- pvalue.onchange = function() {
- if (graph.selected == null)
- return false;
-
- // Change the component property value
- graph.setproperty(graph.selected.comp, pvalue.value);
- pvalue.value = graph.property(graph.selected.comp);
- pvalue.disabled = !graph.hasproperty(graph.selected.comp);
- // Refresh the composite
- graph.refresh(svg);
+ this.curve = function(x1, y1, x, y) {
+ this.path += 'Q' + x1 + ',' + y1 + ' ' + x + ',' + y + ' ';
+ return this.pos(x, y);
+ };
- // Trigger composite change event
- svg.oncomposchange(true);
- return false;
+ this.end = function() {
+ this.path += 'Z';
+ return this;
};
+ }
- // Create a hidden SVG element to help compute the width
- // of component and reference titles
- graph.titlewidthsvg = document.createElementNS(graph.svgns, 'svg');
- graph.titlewidthsvg.style.visibility = 'hidden';
- graph.titlewidthsvg.style.height = 0;
- graph.titlewidthsvg.style.width = 0;
- div.appendChild(graph.titlewidthsvg);
+ return new Path();
+};
- return svg;
- };
+/**
+ * Return an element representing a title.
+ */
+graph.mktitle = function(t, style) {
+ var title = document.createElementNS(graph.svgns, 'text');
+ title.setAttribute('x', 5);
+ title.setAttribute('y', 15);
+ title.setAttribute('text-anchor', 'start');
+ if (style != '')
+ title.style.cssText = style;
+ if (fontsz != '')
+ title.style.fontSize = fontsz;
+ title.style.cursor = 'default';
+ title.appendChild(document.createTextNode(t));
+ return title;
+};
- /**
- * Make a path.
- */
- graph.mkpath = function() {
- function Path() {
- this.BasePath = graph.BasePath;
- this.BasePath();
-
- this.clone = function() {
- return graph.mkpath().pos(this.xpos(), this.ypos());
- };
-
- this.move = function(x, y) {
- this.path += 'M' + x + ',' + y + ' ';
- return this.pos(x, y);
- };
-
- this.line = function(x, y) {
- this.path += 'L' + x + ',' + y + ' ';
- return this.pos(x, y);
- };
-
- this.curve = function(x1, y1, x, y) {
- this.path += 'Q' + x1 + ',' + y1 + ' ' + x + ',' + y + ' ';
- return this.pos(x, y);
- };
-
- this.end = function() {
- this.path += 'Z';
- return this;
- };
- }
+/**
+ * Return an element representing the title of a component.
+ */
+graph.comptitle = function(comp) {
+ return graph.mktitle(graph.title(comp), graph.compstyle(comp));
+};
- return new Path();
- };
+/**
+ * Return the width of the title of a component.
+ */
+graph.comptitlewidth = function(comp) {
+ var title = graph.comptitle(comp);
+ graph.titlewidthsvg.appendChild(title);
+ var width = title.getBBox().width + 2;
+ graph.titlewidthsvg.removeChild(title);
+ return width;
+};
- /**
- * Return an element representing a title.
- */
- graph.mktitle = function(t, style) {
- var title = document.createElementNS(graph.svgns, 'text');
- title.setAttribute('x', 5);
- title.setAttribute('y', 15);
- title.setAttribute('text-anchor', 'start');
- if (style != '')
- title.style.cssText = style;
- if (fontsz != '')
- title.style.fontSize = fontsz;
- title.appendChild(document.createTextNode(t));
- return title;
- };
+/**
+ * Return an element representing the title of a reference.
+ */
+graph.reftitle = function(ref) {
+ return graph.mktitle(graph.title(ref), graph.refstyle(ref));
+};
- /**
- * Return an element representing the title of a component.
- */
- graph.comptitle = function(comp) {
- return graph.mktitle(graph.title(comp), graph.compstyle(comp));
- };
+/**
+ * Return the width of the title of a reference.
+ */
+graph.reftitlewidth = function(ref) {
+ var title = graph.reftitle(ref);
+ graph.titlewidthsvg.appendChild(title);
+ var width = title.getBBox().width;
+ graph.titlewidthsvg.removeChild(title);
+ return width;
+};
- /**
- * Return the width of the title of a component.
- */
- graph.comptitlewidth = function(comp) {
- var title = graph.comptitle(comp);
- graph.titlewidthsvg.appendChild(title);
- var width = title.getBBox().width + 2;
- graph.titlewidthsvg.removeChild(title);
- return width;
- };
+/**
+ * Return an element representing the value of a property.
+ */
+graph.proptitle = function(comp) {
+ var title = graph.mktitle(graph.propertytitle(comp), graph.propstyle(comp));
+ title.setAttribute('x', graph.comptitlewidth(comp) + 7);
+ return title;
+};
- /**
- * Return an element representing the title of a reference.
- */
- graph.reftitle = function(ref) {
- return graph.mktitle(graph.title(ref), graph.refstyle(ref));
- };
+/**
+ * Return the width of the title of a property.
+ */
+graph.proptitlewidth = function(comp) {
+ var title = graph.proptitle(comp);
+ graph.titlewidthsvg.appendChild(title);
+ var width = title.getBBox().width + 4;
+ graph.titlewidthsvg.removeChild(title);
+ return width;
+};
- /**
- * Return the width of the title of a reference.
- */
- graph.reftitlewidth = function(ref) {
- var title = graph.reftitle(ref);
- graph.titlewidthsvg.appendChild(title);
- var width = title.getBBox().width;
- graph.titlewidthsvg.removeChild(title);
- return width;
- };
+/**
+ * Return a node representing a component.
+ */
+graph.compnode = function(comp, cassoc, pos) {
- /**
- * Return an element representing the value of a property.
- */
- graph.proptitle = function(comp) {
- var title = graph.mktitle(graph.propertytitle(comp), graph.propstyle(comp));
- title.setAttribute('x', graph.comptitlewidth(comp) + 7);
- return title;
- };
+ // Make the component and property title elements
+ var title = graph.comptitle(comp);
+ var prop = graph.proptitle(comp);
- /**
- * Return the width of the title of a property.
- */
- graph.proptitlewidth = function(comp) {
- var title = graph.proptitle(comp);
- graph.titlewidthsvg.appendChild(title);
- var width = title.getBBox().width + 4;
- graph.titlewidthsvg.removeChild(title);
- return width;
- };
+ // Compute the path of the component shape
+ var path = graph.comppath(comp, cassoc);
+ var d = path.str();
- /**
- * Return a node representing a component.
- */
- graph.compnode = function(comp, cassoc, pos) {
+ // Create the main component shape
+ var shape = document.createElementNS(graph.svgns, 'path');
+ shape.setAttribute('d', d);
+ shape.setAttribute('fill', graph.color(comp));
+ shape.setAttribute('fill-opacity', '0.60');
- // Make the component and property title elements
- var title = graph.comptitle(comp);
- var prop = graph.proptitle(comp);
-
- // Compute the path of the component shape
- var path = graph.comppath(comp, cassoc);
- var d = path.str();
-
- // Create the main component shape
- var shape = document.createElementNS(graph.svgns, 'path');
- shape.setAttribute('d', d);
- shape.setAttribute('fill', graph.color(comp));
- shape.setAttribute('fill-opacity', '0.60');
-
- // Create an overlay contour shape
- var contour = document.createElementNS(graph.svgns, 'path');
- contour.setAttribute('d', d);
- contour.setAttribute('fill', 'none');
- contour.setAttribute('stroke', graph.colors.gray);
- contour.setAttribute('stroke-width', '3');
- contour.setAttribute('stroke-opacity', '0.20');
- contour.setAttribute('transform', 'translate(1,1)');
-
- // Create a group and add the component and contour shapes to it.
- var g = document.createElementNS(graph.svgns, 'g');
- g.id = scdl.name(comp);
- g.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')');
- g.appendChild(shape);
- g.appendChild(contour);
- g.appendChild(title);
- g.appendChild(prop);
-
- // Store the component and the positions of its services
- // and references in the component shape
- g.comp = comp;
- g.refpos = reverse(path.refpos);
- g.svcpos = reverse(path.svcpos);
+ // Create an overlay contour shape
+ var contour = document.createElementNS(graph.svgns, 'path');
+ contour.setAttribute('d', d);
+ contour.setAttribute('fill', 'none');
+ contour.setAttribute('stroke', graph.colors.gray);
+ contour.setAttribute('stroke-width', '3');
+ contour.setAttribute('stroke-opacity', '0.20');
+ contour.setAttribute('transform', 'translate(1,1)');
- return g;
- };
+ // Create a group and add the component and contour shapes to it.
+ var g = document.createElementNS(graph.svgns, 'g');
+ g.id = scdl.name(comp);
+ g.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')');
+ g.appendChild(shape);
+ g.appendChild(contour);
+ g.appendChild(title);
+ g.appendChild(prop);
- /**
- * Return a graphical group.
- */
- graph.mkgroup = function(pos) {
- var g = document.createElementNS(graph.svgns, 'g');
- g.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')');
- return g;
- };
+ // Store the component and the positions of its services
+ // and references in the component shape
+ g.comp = comp;
+ g.refpos = reverse(path.refpos);
+ g.svcpos = reverse(path.svcpos);
- /**
- * Return a node representing a button.
- */
- graph.mkbutton = function(t, pos) {
+ return g;
+};
- // Make the button title
- var title = graph.mktitle(t, '');
+/**
+ * Return a graphical group.
+ */
+graph.mkgroup = function(pos) {
+ var g = document.createElementNS(graph.svgns, 'g');
+ g.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')');
+ return g;
+};
- // Compute the path of the button shape
- var path = graph.buttonpath().str();
+/**
+ * Return a node representing a button.
+ */
+graph.mkbutton = function(t, pos) {
- // Create the main button shape
- var shape = document.createElementNS(graph.svgns, 'path');
- shape.setAttribute('d', path);
- shape.setAttribute('fill', graph.colors.lightgray);
- shape.setAttribute('fill-opacity', '0.60');
-
- // Create an overlay contour shape
- var contour = document.createElementNS(graph.svgns, 'path');
- contour.setAttribute('d', path);
- contour.setAttribute('fill', 'none');
- contour.setAttribute('stroke', graph.colors.gray);
- contour.setAttribute('stroke-width', '3');
- contour.setAttribute('stroke-opacity', '0.20');
- contour.setAttribute('transform', 'translate(1,1)');
-
- // Create a group and add the button and contour shapes to it
- var g = document.createElementNS(graph.svgns, 'g');
- g.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')');
- g.appendChild(shape);
- g.appendChild(contour);
- g.appendChild(title);
- return g;
- };
+ // Make the button title
+ var title = graph.mktitle(t, '');
- /**
- * Return the relative position of a node.
- */
- graph.relpos = function(e) {
- var pmatrix = e.parentNode.getCTM();
- var matrix = e.getCTM();
- var curX = pmatrix != null? (Number(matrix.e) - Number(pmatrix.e)): Number(matrix.e);
- var curY = pmatrix != null? (Number(matrix.f) - Number(pmatrix.f)): Number(matrix.f);
- return graph.mkpath().move(curX, curY);
- };
+ // Compute the path of the button shape
+ var path = graph.buttonpath().str();
+
+ // Create the main button shape
+ var shape = document.createElementNS(graph.svgns, 'path');
+ shape.setAttribute('d', path);
+ shape.setAttribute('fill', graph.colors.lightgray);
+ shape.setAttribute('fill-opacity', '0.60');
+
+ // Create an overlay contour shape
+ var contour = document.createElementNS(graph.svgns, 'path');
+ contour.setAttribute('d', path);
+ contour.setAttribute('fill', 'none');
+ contour.setAttribute('stroke', graph.colors.gray);
+ contour.setAttribute('stroke-width', '3');
+ contour.setAttribute('stroke-opacity', '0.20');
+ contour.setAttribute('transform', 'translate(1,1)');
+
+ // Create a group and add the button and contour shapes to it
+ var g = document.createElementNS(graph.svgns, 'g');
+ g.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')');
+ g.appendChild(shape);
+ g.appendChild(contour);
+ g.appendChild(title);
+ return g;
+};
- /**
- * Move a node.
- */
- graph.move = function(e, pos) {
- e.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')');
- };
+/**
+ * Return the relative position of a node.
+ */
+graph.relpos = function(e) {
+ var pmatrix = e.parentNode.getCTM();
+ var matrix = e.getCTM();
+ var curX = pmatrix != null? (Number(matrix.e) - Number(pmatrix.e)): Number(matrix.e);
+ var curY = pmatrix != null? (Number(matrix.f) - Number(pmatrix.f)): Number(matrix.f);
+ return graph.mkpath().move(curX, curY);
+};
+
+/**
+ * Move a node.
+ */
+graph.move = function(e, pos) {
+ e.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')');
};
/**
@@ -1725,11 +1259,46 @@ graph.clonepalette = function(e, compos)
* Move a SCDL component to the given position.
*/
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)));
};
/**
+ * Sort elements of a composite.
+ */
+graph.sortcompos = function(compos) {
+ return append(mklist(element, "'composite"), elementChildren(compos).sort(function(a, b) {
+
+ // Sort attributes, place them at the top
+ var aa = isAttribute(a);
+ var ba = isAttribute(b);
+ if (aa && !ba) return -1;
+ if (!aa && ba) return 1;
+ if (aa && ba) {
+ var aan = attributeName(a);
+ var ban = attributeName(b);
+ if (aan < ban) return -1;
+ if (aan > ban) return 1;
+ return 0;
+ }
+
+ // Sort elements, place services before components
+ var aen = elementName(a);
+ var ben = elementName(b);
+ if (aen == "'service" && ben == "'component") return -1;
+ if (aen == "'component" && ben == "'service") return 1;
+ var an = scdl.name(a);
+ var bn = scdl.name(b);
+ if (an < bn) return -1;
+ if (an > bn) return 1;
+ return 0;
+ }));
+}
+
+/**
* Add a component to a SCDL composite.
*/
graph.addcomp = function(comp, compos) {
@@ -1865,7 +1434,7 @@ graph.cutwire = function(node, compos, g
var name = scdl.name(comp);
var prom = mklist(element, "'service", mklist(attribute, "'name", name), mklist(attribute, "'promote", name));
return append(mklist(element, "'composite"),
- append(filter(function(c) { return !(isElement(c) && scdl.name(c) == name); }, elementChildren(compos)), mklist(prom, comp)));
+ append(mklist(prom), filter(function(c) { return !(isElement(c) && elementName(c) == "'service" && scdl.name(c) == name); }, elementChildren(compos))));
}
/**
@@ -1933,6 +1502,7 @@ graph.wire = function(n, compos, g) {
// Wire component to that reference, un-promote it, and
// update the SCDL reference and composite
+ setElement(n.comp, graph.movecomp(graph.dragging.comp, null));
n.compos = null;
setElement(car(cref), append(mklist(element, "'reference", mklist(attribute, "'target", scdl.name(n.comp))), elementChildren(car(cref))));
var name = scdl.name(n.comp);
@@ -1981,6 +1551,10 @@ graph.edit = function(appname, compos, n
g.appname = appname;
g.compos = compos;
+ // Sort the composite elements now to allow for change detection later
+ var scompos = scdl.composite(g.compos);
+ setElement(scompos, graph.sortcompos(scompos));
+
// Store event listeners
g.oncomposchange = onchange;
g.oncompselect = onselect;