demand-matcher.js, jquery-driver.js
This commit is contained in:
parent
8c55ada827
commit
9d7dd37a37
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Syndicate: jQuery Example</title>
|
||||
<meta charset="utf-8">
|
||||
<script src="../../third-party/jquery-2.2.0.min.js"></script>
|
||||
<script src="../../dist/syndicate.js"></script>
|
||||
<script src="index.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>jQuery example</h1>
|
||||
<button id="clicker">Click me</button>
|
||||
<div id="result">0</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,28 @@
|
|||
"use strict";
|
||||
|
||||
var G;
|
||||
$(document).ready(function () {
|
||||
var Network = Syndicate.Network;
|
||||
var sub = Syndicate.sub;
|
||||
var __ = Syndicate.__;
|
||||
var _$ = Syndicate._$;
|
||||
|
||||
G = new Syndicate.Ground(function () {
|
||||
console.log('starting ground boot');
|
||||
|
||||
Syndicate.JQuery.spawnJQueryDriver();
|
||||
|
||||
Network.spawn({
|
||||
boot: function () {
|
||||
return sub(['jQuery', '#clicker', 'click', __]);
|
||||
},
|
||||
handleEvent: function (e) {
|
||||
if (e.type === 'message' && e.message[0] === 'jQuery' && e.message[1] === '#clicker') {
|
||||
var r = $('#result');
|
||||
r.html(Number(r.html()) + 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
G.startStepping();
|
||||
});
|
|
@ -0,0 +1,80 @@
|
|||
var Immutable = require('immutable');
|
||||
var Syndicate = require('./syndicate.js');
|
||||
var Route = require('./route.js');
|
||||
var Patch = require('./patch.js');
|
||||
var Util = require('./util.js');
|
||||
|
||||
function DemandMatcher(demandSpec, supplySpec, options) {
|
||||
options = Util.extend({
|
||||
metaLevel: 0,
|
||||
onDemandIncrease: function (captures) {
|
||||
console.error("Syndicate: Unhandled increase in demand", captures);
|
||||
},
|
||||
onSupplyDecrease: function (captures) {
|
||||
console.error("Syndicate: Unhandled decrease in supply", captures);
|
||||
}
|
||||
}, options);
|
||||
this.metaLevel = options.metaLevel;
|
||||
this.onDemandIncrease = options.onDemandIncrease;
|
||||
this.onSupplyDecrease = options.onSupplyDecrease;
|
||||
this.demandSpec = demandSpec;
|
||||
this.supplySpec = supplySpec;
|
||||
this.demandPattern = Route.projectionToPattern(demandSpec);
|
||||
this.supplyPattern = Route.projectionToPattern(supplySpec);
|
||||
this.demandProjection = Route.compileProjection(demandSpec);
|
||||
this.supplyProjection = Route.compileProjection(supplySpec);
|
||||
this.currentDemand = Immutable.Set();
|
||||
this.currentSupply = Immutable.Set();
|
||||
}
|
||||
|
||||
DemandMatcher.prototype.boot = function () {
|
||||
return Patch.sub(this.demandPattern, this.metaLevel)
|
||||
.andThen(Patch.sub(this.supplyPattern, this.metaLevel));
|
||||
};
|
||||
|
||||
DemandMatcher.prototype.handleEvent = function (e) {
|
||||
if (e.type === "stateChange") {
|
||||
this.handlePatch(e.patch);
|
||||
}
|
||||
};
|
||||
|
||||
DemandMatcher.prototype.handlePatch = function (p) {
|
||||
var self = this;
|
||||
|
||||
var addedDemand = Route.trieKeys(Route.project(p.added, self.demandProjection));
|
||||
var removedDemand = Route.trieKeys(Route.project(p.removed, self.demandProjection));
|
||||
var addedSupply = Route.trieKeys(Route.project(p.added, self.supplyProjection));
|
||||
var removedSupply = Route.trieKeys(Route.project(p.removed, self.supplyProjection));
|
||||
|
||||
if (addedDemand === null) {
|
||||
throw new Error("Syndicate: wildcard demand detected:\n" +
|
||||
self.demandSpec + "\n" +
|
||||
p.pretty());
|
||||
}
|
||||
if (addedSupply === null) {
|
||||
throw new Error("Syndicate: wildcard supply detected:\n" +
|
||||
self.supplySpec + "\n" +
|
||||
p.pretty());
|
||||
}
|
||||
|
||||
self.currentSupply = self.currentSupply.union(addedSupply);
|
||||
self.currentDemand = self.currentDemand.subtract(removedDemand);
|
||||
|
||||
removedSupply.forEach(function (captures) {
|
||||
if (self.currentDemand.has(captures)) {
|
||||
self.onSupplyDecrease(Route.captureToObject(captures, self.supplyProjection));
|
||||
}
|
||||
});
|
||||
addedDemand.forEach(function (captures) {
|
||||
if (!self.currentSupply.has(captures)) {
|
||||
self.onDemandIncrease(Route.captureToObject(captures, self.demandProjection));
|
||||
}
|
||||
});
|
||||
|
||||
self.currentSupply = self.currentSupply.subtract(removedSupply);
|
||||
self.currentDemand = self.currentDemand.union(addedDemand);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module.exports.DemandMatcher = DemandMatcher;
|
|
@ -0,0 +1,90 @@
|
|||
// JQuery event driver
|
||||
var Syndicate = require("./syndicate.js");
|
||||
var Patch = require("./patch.js");
|
||||
var DemandMatcher = require('./demand-matcher.js').DemandMatcher;
|
||||
var Network = Syndicate.Network;
|
||||
var __ = Syndicate.__;
|
||||
var _$ = Syndicate._$;
|
||||
|
||||
function spawnJQueryDriver(baseSelector, metaLevel, wrapFunction) {
|
||||
metaLevel = metaLevel || 0;
|
||||
wrapFunction = wrapFunction || defaultWrapFunction;
|
||||
Network.spawn(
|
||||
new DemandMatcher(Patch.observe(wrapFunction(_$('selector'), _$('eventName'), __)),
|
||||
Patch.advertise(wrapFunction(_$('selector'), _$('eventName'), __)),
|
||||
{
|
||||
metaLevel: metaLevel,
|
||||
onDemandIncrease: function (c) {
|
||||
Network.spawn(new JQueryEventRouter(baseSelector,
|
||||
c.selector,
|
||||
c.eventName,
|
||||
metaLevel,
|
||||
wrapFunction));
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
function defaultWrapFunction(selector, eventName, eventValue) {
|
||||
return ["jQuery", selector, eventName, eventValue];
|
||||
}
|
||||
|
||||
function JQueryEventRouter(baseSelector, selector, eventName, metaLevel, wrapFunction) {
|
||||
var self = this;
|
||||
this.baseSelector = baseSelector || null;
|
||||
this.selector = selector;
|
||||
this.eventName = eventName;
|
||||
this.metaLevel = metaLevel || 0;
|
||||
this.wrapFunction = wrapFunction || defaultWrapFunction;
|
||||
this.preventDefault = (this.eventName.charAt(0) !== "+");
|
||||
this.handler =
|
||||
Network.wrap(function (e) {
|
||||
Network.send(self.wrapFunction(self.selector, self.eventName, e), self.metaLevel);
|
||||
if (self.preventDefault) e.preventDefault();
|
||||
return !self.preventDefault;
|
||||
});
|
||||
this.computeNodes().on(this.preventDefault ? this.eventName : this.eventName.substring(1),
|
||||
this.handler);
|
||||
}
|
||||
|
||||
JQueryEventRouter.prototype.boot = function () {
|
||||
return Patch.pub(this.wrapFunction(this.selector, this.eventName, __), this.metaLevel)
|
||||
.andThen(Patch.sub(Patch.observe(this.wrapFunction(this.selector, this.eventName, __)),
|
||||
this.metaLevel));
|
||||
};
|
||||
|
||||
JQueryEventRouter.prototype.handleEvent = function (e) {
|
||||
if (e.type === "stateChange" && e.patch.hasRemoved()) {
|
||||
this.computeNodes().off(this.eventName, this.handler);
|
||||
Network.exit();
|
||||
}
|
||||
};
|
||||
|
||||
JQueryEventRouter.prototype.computeNodes = function () {
|
||||
if (this.baseSelector) {
|
||||
return $(this.baseSelector).children(this.selector).addBack(this.selector);
|
||||
} else {
|
||||
return $(this.selector);
|
||||
}
|
||||
};
|
||||
|
||||
function simplifyDOMEvent(e) {
|
||||
var keys = [];
|
||||
for (var k in e) {
|
||||
var v = e[k];
|
||||
if (typeof v === 'object') continue;
|
||||
if (typeof v === 'function') continue;
|
||||
keys.push(k);
|
||||
}
|
||||
keys.sort();
|
||||
var simplified = [];
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
simplified.push([keys[i], e[keys[i]]]);
|
||||
}
|
||||
return simplified;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module.exports.spawnJQueryDriver = spawnJQueryDriver;
|
||||
module.exports.simplifyDOMEvent = simplifyDOMEvent;
|
||||
module.exports.defaultWrapFunction = defaultWrapFunction;
|
|
@ -17,8 +17,10 @@ copyKeys(['__', '_$', '$Capture', '$Special',
|
|||
module.exports,
|
||||
module.exports.Route);
|
||||
|
||||
module.exports.DemandMatcher = require('./demand-matcher.js').DemandMatcher;
|
||||
|
||||
// module.exports.DOM = require("./dom-driver.js");
|
||||
// module.exports.JQuery = require("./jquery-driver.js");
|
||||
module.exports.JQuery = require("./jquery-driver.js");
|
||||
// module.exports.RoutingTableWidget = require("./routing-table-widget.js");
|
||||
// module.exports.WebSocket = require("./websocket-driver.js");
|
||||
module.exports.Reflect = require("./reflect.js");
|
||||
|
|
Loading…
Reference in New Issue