Permalink
Browse files

Added API for serializing an XML document to a string.

Added support for inline data, including type parsing.

Exposed XML document parsing API from platform to scripting context.
  • Loading branch information...
1 parent 0640e27 commit f96cf89342f6a24c81cc2c1e08ab0a6f2bb1161d @jbeard4 committed Nov 11, 2012
Showing with 93 additions and 6 deletions.
  1. +4 −0 lib/browser/dom.js
  2. +2 −1 lib/core/scxml/SCXML.js
  3. +37 −1 lib/core/util/annotate-scxml-json.js
  4. +31 −4 lib/core/util/code-gen.js
  5. +6 −0 lib/node/dom.js
  6. +13 −0 lib/rhino/dom.js
View
4 lib/browser/dom.js
@@ -44,4 +44,8 @@ dom.getChildren = function(node){
return toReturn;
};
+dom.serializeToString = function(node){
+ return node.xml || (new XMLSerializer()).serializeToString(node);
+};
+
module.exports = dom;
View
3 lib/core/scxml/SCXML.js
@@ -92,7 +92,8 @@ SCXMLInterpreter.prototype = {
this._send.bind(this),
this.opts.origin,
this.isIn.bind(this),
- actionCodeRequire);
+ actionCodeRequire,
+ pm.platform.parseDocumentFromString);
this._actions = tmp.actions;
this._datamodel = tmp.datamodel;
View
38 lib/core/util/annotate-scxml-json.js
@@ -158,7 +158,43 @@ function transformTransitionNode (transitionNode, parentState) {
function transformDatamodel(node, ancestors) {
pm.platform.dom.getChildren(node).filter(function(child){return pm.platform.dom.localName(child) === 'data';}).forEach(function(child){
if (pm.platform.dom.hasAttribute(child,"id")) {
- datamodel[pm.platform.dom.getAttribute(child,"id")] = pm.platform.dom.hasAttribute(child,"expr") ? pm.platform.dom.getAttribute(child,"expr") : null;
+
+ var datamodelObject;
+
+ var id = pm.platform.dom.getAttribute(child,"id");
+
+ if(pm.platform.dom.hasAttribute(child,"expr")){
+ datamodelObject = {
+ content : pm.platform.dom.getAttribute(child,"expr"),
+ type : 'expr'
+ };
+ }else{
+ var hasType = pm.platform.dom.hasAttribute(child,'type');
+
+
+ //fetch the first text node to get the text content
+ if(hasType){
+ var type = pm.platform.dom.getAttribute(child,'type');
+
+ var textContent = type === 'xml' ?
+ pm.platform.dom.serializeToString(child) :
+ pm.platform.dom.textContent(child);
+
+ datamodelObject = {
+ content : textContent,
+ type : type
+ };
+ }else{
+ textContent = pm.platform.dom.textContent(child);
+ datamodelObject = textContent.length ?
+ {
+ content : textContent,
+ type : 'text'
+ } : null;
+ }
+ }
+
+ datamodel[id] = datamodelObject;
}
});
}
View
35 lib/core/util/code-gen.js
@@ -179,14 +179,39 @@ function getDelayInMs(delayString){
}
}
+function getDatamodelExpression(id, datamodelObject){
+ var s = id;
+
+ if(datamodelObject){
+ s += ' = ';
+
+ switch(datamodelObject.type){
+ case 'xml' :
+ s += '$parseXml(' + JSON.stringify(datamodelObject.content) + ')';
+ break;
+ case 'json' :
+ s += 'JSON.parse(' + JSON.stringify(datamodelObject.content) + ')';
+ break;
+ case 'expr' :
+ s += datamodelObject.content;
+ break;
+ default :
+ s += JSON.stringify(datamodelObject.content);
+ break;
+ }
+ }
+
+ return s;
+}
+
//utility functions
//this creates the string which declares the datamodel in the document scope
function makeDatamodelDeclaration(datamodel){
var s = "var ";
var vars = [];
for(var id in datamodel){
- var expr = datamodel[id];
- vars.push(expr ? id + " = " + expr : id);
+ var datamodelObject = datamodel[id];
+ vars.push(getDatamodelExpression(id,datamodelObject));
}
return vars.length ? (s + vars.join(", ") + ";") : "";
}
@@ -213,14 +238,15 @@ function wrapFunctionBodyInDeclaration(action,isExpression){
function makeTopLevelFunctionBody(datamodelDeclaration,topLevelScripts,datamodelClosures,actionStrings){
return datamodelDeclaration +
(topLevelScripts.length ? topLevelScripts.join("\n") : "") +
+ "var $datamodel = " + datamodelClosures + ";\n" +
"return {\n" +
- "datamodel:" + datamodelClosures + "," +
+ "datamodel:$datamodel,\n" +
"actions:[\n" + actionStrings.join(",\n") + "\n]" + //return all functions which get called during execution
"\n};";
}
function wrapTopLevelFunctionBodyInDeclaration(fnBody){
- return "function($log,$cancel,$send,$origin,In,require){\n" + fnBody + "\n}";
+ return "function($log,$cancel,$send,$origin,In,require,$parseXml){\n" + fnBody + "\n}";
}
//this function ensures that the code in each SCXML document will run in "document scope".
@@ -233,6 +259,7 @@ function makeActionFactory(topLevelScripts,actionStrings,datamodel){
var datamodelClosures = makeDatamodelClosures(datamodel);
var topLevelFnBody = makeTopLevelFunctionBody(datamodelDeclaration,topLevelScripts,datamodelClosures,actionStrings);
var fnStr = wrapTopLevelFunctionBodyInDeclaration(topLevelFnBody);
+ //require('fs').writeFileSync('out.js',fnStr);
return fnStr;
}
View
6 lib/node/dom.js
@@ -17,3 +17,9 @@
"use strict";
module.exports = require('../base-platform/dom'); //pass straight through. no modifications needed
+
+var XMLSerializer = require('xmldom').XMLSerializer;
+
+module.exports.serializeToString = function(node){
+ return (new XMLSerializer()).serializeToString(node);
+};
View
13 lib/rhino/dom.js
@@ -38,4 +38,17 @@ dom.getChildren = function(node){
};
});
+
+dom.serializeToString = function(node){
+ var baos = new Packages.java.io.ByteArrayOutputStream();
+ var serializer = new Packages.org.apache.xml.serialize.XMLSerializer(
+ baos,
+ new Packages.org.apache.xml.serialize.OutputFormat());
+
+ serializer.asDOMSerializer().serialize(node);
+
+ var toReturn = String(new Packages.java.lang.String(baos.toByteArray()));
+ return toReturn;
+};
+
module.exports = dom;

0 comments on commit f96cf89

Please sign in to comment.