Fix XML serialization issues with XHTML docs and add ability to save widgets.

git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1060250 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
jsdelfino 2011-01-18 09:07:34 +00:00
parent cff1c7648d
commit 98a6c20328
11 changed files with 148 additions and 50 deletions
sca-cpp/trunk/modules

View file

@ -27,12 +27,14 @@ def appid(id):
# Post a new app to the apps db
def post(collection, app, cache):
id = appid((str(uuid.uuid1()),))
cache.put((id,), app)
comp = caddr(app)
cache.put((id,), comp)
return id
# Put an app into the apps db
def put(id, app, cache):
cache.put(appid(id), app)
comp = caddr(app)
cache.put(appid(id), comp)
return True
# Get an app from the apps db

View file

@ -27,6 +27,6 @@
<span id="checkout" style="position:absolute; left: 0px; top: 340px"><input type="button" value="Checkout"/></span>
<span id="empty" style="position:absolute; left: 120px; top: 340px"><input type="button" value="Empty"/></span>
<span id="feed" style="position:absolute; left: 240px; top: 340px"><a href="shoppingCart/">(feed)</a></span>
<span id="feed" style="position:absolute; left: 240px; top: 340px"><a href="shoppingCart/"><span>(feed)</span></a></span>
</div>

View file

@ -27,6 +27,6 @@
<span id="checkout" style="position:absolute; left: 0px; top: 340px"><input type="button" value="Checkout"/></span>
<span id="empty" style="position:absolute; left: 120px; top: 340px"><input type="button" value="Empty"/></span>
<span id="feed" style="position:absolute; left: 240px; top: 340px"><a href="shoppingCart/">(feed)</a></span>
<span id="feed" style="position:absolute; left: 240px; top: 340px"><a href="shoppingCart/"><span>(feed)</span></a></span>
</div>

View file

@ -27,6 +27,6 @@
<span id="checkout" style="position:absolute; left: 0px; top: 340px"><input type="button" value="Checkout"/></span>
<span id="empty" style="position:absolute; left: 120px; top: 340px"><input type="button" value="Empty"/></span>
<span id="feed" style="position:absolute; left: 240px; top: 340px"><a href="shoppingCart/">(feed)</a></span>
<span id="feed" style="position:absolute; left: 240px; top: 340px"><a href="shoppingCart/"><span>(feed)</span></a></span>
</div>

View file

@ -33,22 +33,25 @@
<form id="appsForm">
<div id="apps"></div>
<br/>
&gt;<a href="" id="addAppLink">Add</a>&nbsp;<a href="" id="deleteAppLink">Delete</a>
<input type="button" id="createAppButton" value="Create App"/>
</form>
<div id="newApp" style="visibility: hidden;">
<form id="newAppForm">
<table width="100%">
<tr><th>Add a New App</th></tr>
<tr><td>Add a new App to your dashboard.</td></tr>
<tr><th>Create an App</th></tr>
<tr><td></td></tr>
</table>
<br>
<table width="100%">
<tr><td>App name:</td><td><input type="text" id="appName" size="10"/></td></tr>
<tr><td>Title:</td><td><input type="text" id="appTitle" size="20"/></td></tr>
<tr><td><b>App Name:</b></td></tr>
<tr><td><input type="text" id="appName" size="10"/></td></tr>
<tr><tr><td><b>App Title:</b></td></tr>
<tr><td><input type="text" id="appTitle" size="20"/></td></tr>
</table>
<input id="addAppButton" type="button" value="Add"/>
<input id="createAppOKButton" type="button" style="font-weight: bold;" value="Create"/>
<input id="createAppCancelButton" type="button" value="Cancel"/>
</form>
</div>
@ -100,31 +103,46 @@ function getapps(sync) {
}
/**
* Toggle new app form link event.
* Display create app form.
*/
$('addAppLink').onclick = function() {
$('createAppButton').onclick = function() {
var div = $('newApp');
div.style.visibility = div.style.visibility == 'hidden'? 'visible' : 'hidden';
div.style.visibility = 'visible';
$('appName').focus();
return false;
};
/**
* Add a new app button event.
* Create an app.
*/
$('addAppButton').onclick = function() {
$('createAppOKButton').onclick = function() {
var name = $('appName').value;
var title = $('appTitle').value;
var app = mklist(title, name, mklist());
var entry = atom.writeATOMEntry(app);
dashboard.put(name, car(entry));
$('appName').value = '';
$('appTitle').title = '';
getapps();
div.style.visibility = 'visible';
return false;
};
/**
* Delete apps event.
* Cancel creating an app.
*/
$('createAppCancelButton').onclick = function() {
var div = $('newApp');
div.style.visibility = 'hidden';
$('appName').value = '';
$('appTitle').title = '';
return false;
};
/**
* Delete an app.
*/
/*
$('deleteAppLink').onclick = function() {
var apps = $('appsForm').apps;
if (isNil(apps))
@ -140,6 +158,7 @@ $('deleteAppLink').onclick = function() {
getapps();
return false;
};
*/
// Get and display the list of apps
getapps(true);

View file

@ -31,7 +31,7 @@
<body>
<table style="position: absolute; top: 0px; left: 0px;" width="100%">
<tr><th style="width: 338px;">Palette</th><th>App</th></tr>
<tr><th style="width: 338px;">Palette</th><th style="padding-top: 0px; padding-bottom: 0px;"><span>App</span><span style="position: absolute; top: 2px; right: 8px;"><input type="button" id="saveButton" style="font-weight: bold;" Value="Save"/></span></th></tr>
</table>
<script type="text/javascript">
@ -40,7 +40,7 @@ var palettes = sca.reference(editWidget, "palettes");
var apps = sca.reference(editWidget, "apps");
// Setup remote log
rconsole = sca.defun(sca.reference(editWidget, "log"), "log");
//rconsole = sca.defun(sca.reference(editWidget, "log"), "log");
/**
* Return the current app name.

View file

@ -31,7 +31,7 @@
<body>
<table style="position: absolute; top: 0px; left: 0px;" width="100%">
<tr><th style="width: 338px;">Palette</th><th>Page</th></tr>
<tr><th style="width: 338px;">Palette</th><th style="padding-top: 0px; padding-bottom: 0px;"><span>Page</span><span style="position: absolute; top: 2px; right: 8px;"><input type="button" id="saveButton" style="font-weight: bold;" Value="Save"/></span></th></tr>
</table>
<div id="page" style="position: absolute; top: 60px; left: 0px; width: 5000px; height: 5000px;">
@ -41,9 +41,9 @@
<span id="palette:button" style="position: absolute; left: 0px; top: 80px;"><input type="button" value="button"/></span>
<span id="palette:entry" style="position: absolute; left: 0px; top: 120px;"><input type="text" value="field" size="5"/></span>
<span id="palette:password" style="position: absolute; left: 0px; top: 160px;"><input type="password" value="password" size="5"/></span>
<span id="palette:checkbox" style="position: absolute; left: 0px; top: 200px;"><input type="checkbox" value="checkbox"/>checkbox</span>
<span id="palette:checkbox" style="position: absolute; left: 0px; top: 200px;"><input type="checkbox" value="checkbox"></input><span>checkbox</span></span>
<span id="palette:select" style="position: absolute; left: 0px; top: 240px;"><select><option value="list">list</option></select></span>
<span id="palette:link" style="position: absolute; left: 0px; top: 280px;"><a href="">link</a></span>
<span id="palette:link" style="position: absolute; left: 0px; top: 280px;"><a href="/"><span>link</span></a></span>
<span id="palette:text" style="position: absolute; left: 0px; top: 320px;"><span>text</span></span>
<span id="palette:img" style="position: absolute; left: 0px; top: 360px;"><img/></span>
@ -75,32 +75,72 @@ function atompage(doc) {
/**
* Get and display an app page.
*/
function getpage(name, e) {
function getpage(name, edit) {
if (isNil(name))
return;
pages.get(name, function(doc) {
// Convert the page to XML
var x = writeStrings(writeXML(atompage(doc), false));
// Convert the page to XHTML
var xhtml = writeStrings(writeXML(atompage(doc), false));
// Prepare page DOM in hidden buffer
var buffer = $('buffer');
buffer.innerHTML = x;
buffer.innerHTML = xhtml;
// Append page nodes to editor
map(function(e) {
e.style.left = ui.posn(e.style.left) + 350;
pageedit.appendChild(e);
edit.appendChild(e);
return page.cover(e);
}, nodeList(buffer.childNodes[0].childNodes));
});
}
/**
* Save the current edited page.
*/
$('saveButton').onclick = function(e) {
// Copy page DOM to hidden buffer
var edit = $('page');
var buffer = $('buffer');
buffer.innerHTML = '<div id="page"></div>'
var div = buffer.childNodes[0];
div.innerHTML = edit.innerHTML;
// Remove nodes from palette and editor artifacts, which are
// not part of the page, as well as nodes positioned out of
// the editing area
map(function(e) {
if (isNil(e.id) || e.id == '' || e.id.substr(0, 8) == 'palette:') {
div.removeChild(e);
return e;
}
var x = ui.posn(e.style.left) - 350;
if (x < 0 || ui.posn(e.style.top) < 0) {
div.removeChild(e);
return e;
}
e.style.left = x;
return e;
}, nodeList(div.childNodes));
// Convert the page to XHTML
var lxhtml = readXHTMLElement(div);
var xhtml = writeStrings(writeXML(lxhtml, false));
// Update the page ATOM entry
var name = appname();
var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">' + name + '</title><id>' + name + '</id><content type="application/xml"><item>' +
xhtml + '</item></content></entry>';
pages.put(name, entry, function(e) {});
};
// Initialize the page editor
var pageedit = $('page');
page.initpage(pageedit);
var edit = $('page');
page.initpage(edit);
// Get and display the current app page
getpage(appname(), pageedit);
getpage(appname(), edit);
</script>
</body>

View file

@ -18,6 +18,7 @@
# App pages collection implementation
import uuid
import sys
from sys import stderr
from util import *
# Convert an id to an app id
@ -27,12 +28,14 @@ def appid(id):
# Post a new app page to the apps db
def post(collection, app, cache):
id = appid((str(uuid.uuid1()),))
cache.put((id,), app)
xhtml = caddr(app);
cache.put((id,), xhtml)
return id
# Put an app page into the apps db
def put(id, app, cache):
cache.put(appid(id), app)
xhtml = caddr(app);
cache.put(appid(id), xhtml)
return True
# Get an app page from the apps db

View file

@ -17,7 +17,7 @@
# specific language governing permissions and limitations
# under the License.
../http/httpd-conf tmp 10.1.1.62 8090 htdocs
../http/httpd-conf tmp localhost 8090 htdocs
../server/server-conf tmp
../python/python-conf tmp
cat >>tmp/conf/httpd.conf <<EOF

View file

@ -29,7 +29,7 @@ font-family: arial,sans-serif; font-style: normal; font-variant: normal; font-si
th {
font-weight: bold; background-color: #e5ecf9; color: #598edd;
text-align: left; padding-left: 2px; padding-right: 8px; padding-top: 2px; padding-bottom: 2px; vertical-align: text-top;
text-align: left; padding-left: 2px; padding-right: 8px; padding-top: 2px; padding-bottom: 4px; vertical-align: text-top;
border-top: 1px; border-bottom: 1px; border-left: 0px; border-right: 0px;
border-style: solid; border-top-color: #a2bae7; border-bottom-color: #d1d3d4;
}

View file

@ -47,7 +47,8 @@ function appendNodes(nodes, p) {
* Return the child attributes of an element.
*/
function childAttributes(e) {
return filter(function(n) { return n.nodeType == 2; }, nodeList(e.attributes));
return filter(function(n) {
return n.nodeType == 2; }, nodeList(e.attributes));
}
/**
@ -67,17 +68,18 @@ function childText(e) {
/**
* Read a list of XML attributes.
*/
function readAttributes(a) {
function readAttributes(p, a) {
if (isNil(a))
return a;
return cons(mklist(attribute, "'" + car(a).nodeName, car(a).nodeValue), readAttributes(cdr(a)));
var x = car(a);
return cons(mklist(attribute, "'" + x.nodeName, x.nodeValue), readAttributes(p, cdr(a)));
}
/**
* Read an XML element.
*/
function readElement(e) {
var l = append(append(mklist(element, "'" + e.nodeName), readAttributes(childAttributes(e))), readElements(childElements(e)));
function readElement(e, childf) {
var l = append(append(mklist(element, "'" + e.nodeName), readAttributes(e, childf(e))), readElements(childElements(e), childf));
var t = childText(e);
if (isNil(t))
return l;
@ -87,10 +89,10 @@ function readElement(e) {
/**
* Read a list of XML elements.
*/
function readElements(l) {
function readElements(l, childf) {
if (isNil(l))
return l;
return cons(readElement(car(l)), readElements(cdr(l)));
return cons(readElement(car(l), childf), readElements(cdr(l), childf));
}
/**
@ -108,7 +110,7 @@ function isXML(l) {
function parseXML(l) {
var s = writeStrings(l);
if (window.DOMParser) {
var p =new DOMParser();
var p = new DOMParser();
return p.parseFromString(s, "text/xml");
}
var doc;
@ -129,7 +131,36 @@ function readXMLDocument(doc) {
var root = childElements(doc);
if (isNil(root))
return mklist();
return mklist(readElement(car(root)));
return mklist(readElement(car(root), childAttributes));
}
/**
* Read a list of values from an XHTML element.
*/
function readXHTMLElement(xhtml) {
// Special XHTML attribute filtering on IE
function ieChildAttributes(e) {
var a = filter(function(n) {
// Filter out empty and internal DOM attributes
if (n.nodeType != 2 || isNil(n.nodeValue) || n.nodeValue == '')
return false;
if (n.nodeName == 'contentEditable' || n.nodeName == 'maxLength' || n.nodeName == 'loop' || n.nodeName == 'start')
return false;
return true;
}, nodeList(e.attributes));
if (e.style.cssText == '')
return a;
// Add style attribute
var sa = new Object();
sa.nodeName = 'style';
sa.nodeValue = e.style.cssText;
return cons(sa, a);
}
var childf = (typeof(XMLSerializer) != 'undefined')? childAttributes : ieChildAttributes;
return mklist(readElement(xhtml, childf));
}
/**
@ -207,17 +238,20 @@ function writeList(l, node, doc) {
return node;
}
/**
* Make a new XML document.
*/
function mkXMLDocument() {
if (document.implementation && document.implementation.createDocument)
return document.implementation.createDocument('', '', null);
return new ActiveXObject("MSXML2.DOMDocument");
}
/**
* Convert a list of values to a list of strings representing an XML document.
*/
function writeXML(l, xmlTag) {
function mkdoc() {
if (document.implementation && document.implementation.createDocument)
return document.implementation.createDocument('', '', null);
return new ActiveXObject("MSXML2.DOMDocument");
}
var doc = mkdoc();
var doc = mkXMLDocument();
writeList(l, doc, doc);
if (!xmlTag)
return writeXMLDocument(doc);