diff --git a/js/examples/iot/index.js b/js/examples/iot/index.js
index 3293a56..8ff23b3 100644
--- a/js/examples/iot/index.js
+++ b/js/examples/iot/index.js
@@ -15,7 +15,7 @@ function spawnTV() {
actor {
react {
during tvAlert($text) {
- assert DOM('#tv', 'alert', Syndicate.seal(["li", text]));
+ assert DOM('#tv', 'alert', Mustache.render($('#alert_template').html(), { text: text }));
}
}
}
@@ -68,9 +68,9 @@ function spawnStoveSwitch() {
assert switchState(this.powerOn);
assert DOM('#stove-switch', 'switch-state',
- Syndicate.seal(["img", [["src",
- "img/stove-coil-element-" +
- (this.powerOn ? "hot" : "cold") + ".jpg"]]]));
+ Mustache.render($('#stove_element_template').html(),
+ { imgurl: ("img/stove-coil-element-" +
+ (this.powerOn ? "hot" : "cold") + ".jpg") }));
on message jQueryEvent('#stove-switch-on', 'click', _) { this.powerOn = true; }
on message jQueryEvent('#stove-switch-off', 'click', _) { this.powerOn = false; }
@@ -92,9 +92,7 @@ function spawnPowerDrawMonitor() {
assert powerDraw(this.watts);
assert DOM('#power-draw-meter', 'power-draw',
- Syndicate.seal(["p", "Power draw: ",
- ["span", [["class", "power-meter-display"]],
- this.watts + " W"]]));
+ Mustache.render($('#power_draw_template').html(), { watts: this.watts }));
on asserted switchState($on) {
this.watts = on ? 1500 : 0;
diff --git a/js/examples/iot/style.css b/js/examples/iot/style.css
index 2fd6050..0f34cb3 100644
--- a/js/examples/iot/style.css
+++ b/js/examples/iot/style.css
@@ -1,3 +1,7 @@
+template {
+ display: none;
+}
+
#tv-container {
background: url('img/tvscreen.gif');
background-size: 100%;
diff --git a/js/examples/svg/index.js b/js/examples/svg/index.js
index 485db4d..279d06b 100644
--- a/js/examples/svg/index.js
+++ b/js/examples/svg/index.js
@@ -19,15 +19,11 @@ $(document).ready(function () {
this.handX = 50 + 40 * Math.cos(this.angle);
this.handY = 50 + 40 * Math.sin(this.angle);
}
- assert DOM('#clock', 'clock', Syndicate.seal(
- ["svg", [["xmlns", "http://www.w3.org/2000/svg"],
- ["width", "300px"],
- ["viewBox", "0 0 100 100"]],
- ["circle", [["fill", "#0B79CE"],
- ["r", 45], ["cx", 50], ["cy", 50]]],
- ["line", [["stroke", "#023963"],
- ["x1", 50], ["y1", 50],
- ["x2", this.handX], ["y2", this.handY]]]]))
+ assert DOM('#clock', 'clock',
+ '')
when (typeof this.angle === 'number');
}
}
diff --git a/js/src/dom-driver.js b/js/src/dom-driver.js
index ddffcbf..57c540c 100644
--- a/js/src/dom-driver.js
+++ b/js/src/dom-driver.js
@@ -3,7 +3,6 @@ var Patch = require("./patch.js");
var DemandMatcher = require('./demand-matcher.js').DemandMatcher;
var Struct = require('./struct.js');
var Ack = require('./ack.js').Ack;
-var Seal = require('./seal.js').Seal;
var Dataspace_ = require("./dataspace.js");
var Dataspace = Dataspace_.Dataspace;
@@ -89,57 +88,28 @@ DOMFragment.prototype.handleEvent = function (e) {
///////////////////////////////////////////////////////////////////////////
-function isAttributes(x) {
- return Array.isArray(x) && ((x.length === 0) || Array.isArray(x[0]));
-}
-
-DOMFragment.prototype.interpretSpec = function (spec, xmlns) {
- // Fragment specs are roughly JSON-equivalents of SXML.
- // spec ::== ["tag", [["attr", "value"], ...], spec, spec, ...]
- // | ["tag", spec, spec, ...]
- // | "cdata"
- if (typeof(spec) === "string" || typeof(spec) === "number") {
- return document.createTextNode(spec);
- } else if ($.isArray(spec)) {
- var tagName = spec[0];
- var hasAttrs = isAttributes(spec[1]);
- var attrs = hasAttrs ? spec[1] : [];
- var kidIndex = hasAttrs ? 2 : 1;
-
- var xmlnsAttr = attrs.find(function (e) { return e[0] === 'xmlns' });
- if (xmlnsAttr) {
- xmlns = xmlnsAttr[1];
- }
-
- // TODO: Wow! Such XSS! Many hacks! So vulnerability! Amaze!
- var n = xmlns
- ? document.createElementNS(xmlns, tagName)
- : document.createElement(tagName);
- for (var i = 0; i < attrs.length; i++) {
- if (attrs[i][0] !== 'xmlns') n.setAttribute(attrs[i][0], attrs[i][1]);
- }
- for (var i = kidIndex; i < spec.length; i++) {
- n.appendChild(this.interpretSpec(spec[i], xmlns));
- }
- return n;
- } else {
- throw new Error("Ill-formed DOM specification");
- }
-};
-
DOMFragment.prototype.buildNodes = function () {
var self = this;
var nodes = [];
$(self.selector).each(function (index, domNode) {
- if (!(self.fragmentSpec instanceof Syndicate.Seal)) {
- throw new Error("DOM fragmentSpec not contained in a Syndicate.Seal: " + JSON.stringify(self.fragmentSpec));
+ if (typeof self.fragmentSpec !== 'string') {
+ throw new Error("DOM fragmentSpec not a string: " + JSON.stringify(self.fragmentSpec));
}
- var n = self.interpretSpec(self.fragmentSpec.sealContents, '');
- if ('classList' in n) {
- n.classList.add(self.fragmentClass);
+ var newNodes = $('
' + self.fragmentSpec + '
')[0].childNodes;
+ // This next loop looks SUPER SUSPICIOUS. What is happening is
+ // that each time we call domNode.appendChild(n), where n is an
+ // element of the NodeList newNodes, the DOM is **removing** n
+ // from the NodeList in order to place it in its new parent. So,
+ // each call to appendChild shrinks the NodeList by one node until
+ // it is finally empty, and its length property yields zero.
+ while (newNodes.length) {
+ var n = newNodes[0];
+ if ('classList' in n) {
+ n.classList.add(self.fragmentClass);
+ }
+ domNode.appendChild(n);
+ nodes.push(n);
}
- domNode.appendChild(n);
- nodes.push(n);
});
return nodes;
};