uiFragmentExists -> uiFragmentVersion

This commit is contained in:
Tony Garnock-Jones 2016-11-30 16:05:02 +13:00
parent c2ece35bf9
commit 0facbc90b3
1 changed files with 23 additions and 7 deletions

View File

@ -52,7 +52,7 @@ var uiFragment = Struct.makeConstructor('ui-fragment',
['fragmentId', 'selector', 'html', 'orderBy']); ['fragmentId', 'selector', 'html', 'orderBy']);
// Assertion. Asserted by respondent to a given uiFragment. // Assertion. Asserted by respondent to a given uiFragment.
var uiFragmentExists = Struct.makeConstructor('ui-fragment-exists', ['fragmentId']); var uiFragmentVersion = Struct.makeConstructor('ui-fragment-version', ['fragmentId', 'version']);
// Assertion. Causes the setup of DOM attributes on all nodes named by // Assertion. Causes the setup of DOM attributes on all nodes named by
// the given selector that exist at the time of assertion. // the given selector that exist at the time of assertion.
@ -114,7 +114,7 @@ function spawnUIDriver(options) {
Dataspace.spawn( Dataspace.spawn(
new DemandMatcher([uiFragment(_$('fragmentId'), __, __, __)], new DemandMatcher([uiFragment(_$('fragmentId'), __, __, __)],
[uiFragmentExists(_$('fragmentId'))], [uiFragmentVersion(_$('fragmentId'), __)],
function (c) { function (c) {
Dataspace.spawn(new UIFragment(c.fragmentId)); Dataspace.spawn(new UIFragment(c.fragmentId));
}, { name: 'uiFragmentSupervisor' })); }, { name: 'uiFragmentSupervisor' }));
@ -154,7 +154,7 @@ GlobalEventSupply.prototype.boot = function () {
this.updateEventListeners(true); this.updateEventListeners(true);
return Patch.sub(this.demandPat) // track demand return Patch.sub(this.demandPat) // track demand
.andThen(Patch.sub(uiFragmentExists(__))) // track new fragments .andThen(Patch.sub(uiFragmentVersion(__, __))) // track new fragments
.andThen(Patch.pub(globalEvent(this.selector, this.eventType, __))) // indicate our presence .andThen(Patch.pub(globalEvent(this.selector, this.eventType, __))) // indicate our presence
; ;
}; };
@ -177,7 +177,7 @@ GlobalEventSupply.prototype.handleDomEvent = function (event) {
GlobalEventSupply.prototype.handleEvent = function (e) { GlobalEventSupply.prototype.handleEvent = function (e) {
this.updateEventListeners(true); this.updateEventListeners(true);
// TODO: don't be so crude about this ^. On the one hand, this lets // TODO: don't be so crude about this ^. On the one hand, this lets
// us ignore uiFragmentExists records coming and going; on the other // us ignore uiFragmentVersion records coming and going; on the other
// hand, we do potentially a lot of redundant work. // hand, we do potentially a lot of redundant work.
if (e.type === 'stateChange' && e.patch.project(this.demandPat).hasRemoved()) { if (e.type === 'stateChange' && e.patch.project(this.demandPat).hasRemoved()) {
Dataspace.exit(); // trapexit will uninstall event listeners Dataspace.exit(); // trapexit will uninstall event listeners
@ -245,9 +245,10 @@ function UIFragment(fragmentId) {
this.name = ['uiFragment', fragmentId]; this.name = ['uiFragment', fragmentId];
} }
var nextVersion = 0;
UIFragment.prototype.boot = function () { UIFragment.prototype.boot = function () {
return Patch.sub(Trie.projectionToPattern(this.demandProj)) // track demand return Patch.sub(Trie.projectionToPattern(this.demandProj)) // track demand
.andThen(Patch.assert(uiFragmentExists(this.fragmentId))) // assert presence .andThen(Patch.assert(uiFragmentVersion(this.fragmentId, nextVersion++))) // assert presence
.andThen(Patch.sub(Trie.projectionToPattern(this.eventDemandProj))) .andThen(Patch.sub(Trie.projectionToPattern(this.eventDemandProj)))
// ^ track demand for fragment-specific events // ^ track demand for fragment-specific events
; ;
@ -398,7 +399,12 @@ UIFragment.prototype.handleEvent = function (e) {
if (e.type === 'stateChange') { if (e.type === 'stateChange') {
var fragmentChanges = e.patch.projectObjects(self.demandProj); var fragmentChanges = e.patch.projectObjects(self.demandProj);
fragmentChanges[0].forEach(function (c) { self.updateContent(c.selector, c.html, c.orderBy); }); var hasChanged = false;
fragmentChanges[0].forEach(function (c) {
self.updateContent(c.selector, c.html, c.orderBy);
hasChanged = true;
});
fragmentChanges[1].forEach(function (c) { fragmentChanges[1].forEach(function (c) {
if (c.selector === self.currentSelector if (c.selector === self.currentSelector
&& c.html === self.currentHtml && c.html === self.currentHtml
@ -411,6 +417,12 @@ UIFragment.prototype.handleEvent = function (e) {
var eventDemand = e.patch.projectObjects(self.eventDemandProj); var eventDemand = e.patch.projectObjects(self.eventDemandProj);
eventDemand[0].forEach(function (c) { self.updateEventListeners(c, true); }) eventDemand[0].forEach(function (c) { self.updateEventListeners(c, true); })
eventDemand[1].forEach(function (c) { self.updateEventListeners(c, false); }) eventDemand[1].forEach(function (c) { self.updateEventListeners(c, false); })
if (hasChanged) {
Dataspace.stateChange(Patch.retract(uiFragmentVersion(this.fragmentId, __))
.andThen(Patch.assert(uiFragmentVersion(this.fragmentId,
nextVersion++))));
}
} }
}; };
@ -655,6 +667,10 @@ Anchor.prototype.event = function (selector, eventType, event) {
return uiEvent(this.fragmentId, selector, eventType, event); return uiEvent(this.fragmentId, selector, eventType, event);
}; };
Anchor.prototype.fragmentVersion = function (v) {
return uiFragmentVersion(this.fragmentId, v);
};
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
function LocationHashTracker(defaultLocationHash) { function LocationHashTracker(defaultLocationHash) {
@ -742,7 +758,7 @@ module.exports.globalEvent = globalEvent;
module.exports.windowEvent = windowEvent; module.exports.windowEvent = windowEvent;
module.exports.uiEvent = uiEvent; module.exports.uiEvent = uiEvent;
module.exports.uiFragment = uiFragment; module.exports.uiFragment = uiFragment;
module.exports.uiFragmentExists = uiFragmentExists; module.exports.uiFragmentVersion = uiFragmentVersion;
module.exports.uiAttribute = uiAttribute; module.exports.uiAttribute = uiAttribute;
module.exports.uiProperty = uiProperty; module.exports.uiProperty = uiProperty;
module.exports.setAttribute = setAttribute; module.exports.setAttribute = setAttribute;