diff --git a/src/dom-driver.js b/src/dom-driver.js index ef9e5d7..6f065f2 100644 --- a/src/dom-driver.js +++ b/src/dom-driver.js @@ -6,31 +6,45 @@ var pub = Minimart.pub; var __ = Minimart.__; var _$ = Minimart._$; -function spawnDOMDriver() { - var d = new Minimart.DemandMatcher(["DOM", _$, _$, _$]); +function spawnDOMDriver(domWrapFunction, jQueryWrapFunction) { + domWrapFunction = domWrapFunction || defaultWrapFunction; + var d = new Minimart.DemandMatcher(domWrapFunction(_$, _$, _$)); d.onDemandIncrease = function (captures) { var selector = captures[0]; var fragmentClass = captures[1]; var fragmentSpec = captures[2]; - World.spawn(new DOMFragment(selector, fragmentClass, fragmentSpec), - [sub(["DOM", selector, fragmentClass, fragmentSpec]), - sub(["DOM", selector, fragmentClass, fragmentSpec], 0, 1)]); + World.spawn(new DOMFragment(selector, + fragmentClass, + fragmentSpec, + domWrapFunction, + jQueryWrapFunction), + [sub(domWrapFunction(selector, fragmentClass, fragmentSpec)), + sub(domWrapFunction(selector, fragmentClass, fragmentSpec), 0, 1)]); }; World.spawn(d); } -function DOMFragment(selector, fragmentClass, fragmentSpec) { +function defaultWrapFunction(selector, fragmentClass, fragmentSpec) { + return ["DOM", selector, fragmentClass, fragmentSpec]; +} + +function DOMFragment(selector, fragmentClass, fragmentSpec, domWrapFunction, jQueryWrapFunction) { this.selector = selector; this.fragmentClass = fragmentClass; this.fragmentSpec = fragmentSpec; + this.domWrapFunction = domWrapFunction; + this.jQueryWrapFunction = jQueryWrapFunction; this.nodes = this.buildNodes(); } DOMFragment.prototype.boot = function () { var self = this; - var monitoring = sub(["DOM", self.selector, self.fragmentClass, self.fragmentSpec], 1, 2); + var monitoring = + sub(this.domWrapFunction(self.selector, self.fragmentClass, self.fragmentSpec), 1, 2); World.spawn(new World(function () { - Minimart.JQuery.spawnJQueryDriver(self.selector+" > ."+self.fragmentClass, 1); + Minimart.JQuery.spawnJQueryDriver(self.selector+" > ."+self.fragmentClass, + 1, + self.jQueryWrapFunction); World.spawn({ handleEvent: function (e) { if (e.type === "routes") { @@ -98,3 +112,4 @@ DOMFragment.prototype.buildNodes = function () { /////////////////////////////////////////////////////////////////////////// module.exports.spawnDOMDriver = spawnDOMDriver; +module.exports.defaultWrapFunction = defaultWrapFunction; diff --git a/src/jquery-driver.js b/src/jquery-driver.js index bc1d8a7..17731cd 100644 --- a/src/jquery-driver.js +++ b/src/jquery-driver.js @@ -6,30 +6,40 @@ var pub = Minimart.pub; var __ = Minimart.__; var _$ = Minimart._$; -function spawnJQueryDriver(baseSelector, metaLevel) { +function spawnJQueryDriver(baseSelector, metaLevel, wrapFunction) { metaLevel = metaLevel || 0; - var d = new Minimart.DemandMatcher(["jQuery", _$, _$, __], metaLevel, + wrapFunction = wrapFunction || defaultWrapFunction; + var d = new Minimart.DemandMatcher(wrapFunction(_$, _$, __), metaLevel, {demandSideIsSubscription: true}); d.onDemandIncrease = function (captures) { var selector = captures[0]; var eventName = captures[1]; - World.spawn(new JQueryEventRouter(baseSelector, selector, eventName, metaLevel), - [pub(["jQuery", selector, eventName, __], metaLevel), - pub(["jQuery", selector, eventName, __], metaLevel, 1)]); + World.spawn(new JQueryEventRouter(baseSelector, + selector, + eventName, + metaLevel, + wrapFunction), + [pub(wrapFunction(selector, eventName, __), metaLevel), + pub(wrapFunction(selector, eventName, __), metaLevel, 1)]); }; World.spawn(d); } -function JQueryEventRouter(baseSelector, selector, eventName, metaLevel) { +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 = World.wrap(function (e) { - World.send(["jQuery", self.selector, self.eventName, e], self.metaLevel); + World.send(self.wrapFunction(self.selector, self.eventName, e), self.metaLevel); if (self.preventDefault) e.preventDefault(); return !self.preventDefault; }); @@ -52,6 +62,24 @@ JQueryEventRouter.prototype.computeNodes = function () { } }; +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; diff --git a/src/routing-table-widget.js b/src/routing-table-widget.js index 814a6f7..19c14a5 100644 --- a/src/routing-table-widget.js +++ b/src/routing-table-widget.js @@ -6,9 +6,10 @@ var pub = Minimart.pub; var __ = Minimart.__; var _$ = Minimart._$; -function spawnRoutingTableWidget(selector, fragmentClass, observationLevel) { +function spawnRoutingTableWidget(selector, fragmentClass, domWrap, observationLevel) { observationLevel = observationLevel || 10; // ^ arbitrary: should be Infinity, when route.js supports it. TODO + domWrap = domWrap || Minimart.DOM.defaultWrapFunction; World.spawn({ boot: function () { this.updateState(); }, @@ -17,8 +18,8 @@ function spawnRoutingTableWidget(selector, fragmentClass, observationLevel) { nextState: Route.emptyGestalt.serialize(), timer: false, - localGestalt: (sub( ["DOM", selector, fragmentClass, __], 0, 2) - .union(pub(["DOM", selector, fragmentClass, __], 0, 2)) + localGestalt: (sub( domWrap(selector, fragmentClass, __), 0, 2) + .union(pub(domWrap(selector, fragmentClass, __), 0, 2)) .telescoped()), digestGestalt: function (g) { @@ -29,7 +30,7 @@ function spawnRoutingTableWidget(selector, fragmentClass, observationLevel) { var elts = ["pre", Route.deserializeGestalt(this.state).pretty()]; World.updateRoutes([sub(__, 0, observationLevel), pub(__, 0, observationLevel), - pub(["DOM", selector, fragmentClass, elts])]); + pub(domWrap(selector, fragmentClass, elts))]); }, handleEvent: function (e) {