Skip to content

Commit

Permalink
Add mutation tracking for distributedNodes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Steven Orvell committed Aug 13, 2015
1 parent 393ba40 commit b11f86b
Show file tree
Hide file tree
Showing 8 changed files with 413 additions and 223 deletions.
22 changes: 21 additions & 1 deletion src/lib/dom-api-flush.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,18 @@
_FLUSH_MAX: 100,
_needsTakeRecords: !Polymer.Settings.useNativeCustomElements,
_debouncers: [],
_preFlushList: [],
_finishDebouncer: null,

// flush and debounce exposed as statics on Polymer.dom
flush: function() {
for (var i=0; i < this._preFlushList.length; i++) {
this._preFlushList[i]();
}
this._flush();
},

_flush: function() {
// flush debouncers
for (var i=0; i < this._debouncers.length; i++) {
this._debouncers[i].complete();
Expand All @@ -34,7 +42,7 @@
// flush again if there are now any debouncers to process
if (this._debouncers.length && this._flushGuard < this._FLUSH_MAX) {
this._flushGuard++;
this.flush();
this._flush();
} else {
if (this._flushGuard >= this._FLUSH_MAX) {
console.warn('Polymer.dom.flush aborted. Flush may not be complete.')
Expand All @@ -52,6 +60,18 @@
}
},

addPreflush: function(fn) {
this._preFlushList.push(fn);
},

// TODO(sorvell): Map when we can?
removePreflush: function(fn) {
var i = this._preFlushList.indexOf(fn);
if (i >= 0) {
this._preFlushList.splice(i, 1);
}
},

addDebouncer: function(debouncer) {
this._debouncers.push(debouncer);
// ensure the list of active debouncers is cleared when done.
Expand Down
172 changes: 72 additions & 100 deletions src/lib/dom-api-mutation-content.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,113 +15,85 @@
var DomApi = Polymer.DomApi.ctor;
var Settings = Polymer.Settings;

DomApi.prototype.observeDistributedNodes = function(callback) {
if (!this._observer) {
this._observer = new DomApi.Mutation(this);
}
return this._observer.addObserver(callback);
};

DomApi.prototype.unobserveDistributedNodes = function(handle) {
if (this._observer) {
this._observer.removeObserver(handle);
}
}

DomApi.MutationContent = function(domApi) {
this.domApi = domApi;
this.node = this.domApi.node;
this._observers = [];
this._addedNodes = [];
this._removedNodes = [];
DomApi.Mutation.call(this, domApi);
};

DomApi.MutationContent.prototype = {

// addObserver: function(callback) {
// return this._observers.push(callback);
// },

// removeObserver: function(handle) {
// this._observers.splice(handle - 1, 1);
// },

// hasObservers: function() {
// return Boolean(this._observers.length);
// },

// _scheduleMutationNotify: function() {
// this._mutationDebouncer = Polymer.Debounce(this._mutationDebouncer,
// this._notifyObservers);
// this._mutationDebouncer.context = this;
// Polymer.dom.addDebouncer(this._mutationDebouncer);
// },

// _notifyObservers: function(mxns) {
// var info = {
// target: this.node,
// addedNodes: this._addedNodes,
// removedNodes: this._removedNodes
// }
// var o$ = this._observers;
// for (var i=0, o; (i < o$.length) && (o=o$[i]); i++) {
// o.call(null, info);
// }
// this._addedNodes = [];
// this._removedNodes = [];
// }

// observeDistributedNodes: function(callback) {
// if (this.node.localName !== 'content') {
// console.warn('Must call `observeDistributedNodes` on a <content> element.');
// return;
// }
// // setup <content>.getDistributedNodes observation
// if (!this.hasObservers()) {
// this._startObserveDistributedNodes();
// }
// this._addObserver(callback);
// },

// unobserveDistributedNodes: function(handle) {
// if (this.node.localName !== 'content') {
// return;
// }
// this._removeObserver(handle);
// if (!this.hasObservers()) {
// this._stopObservingDistributedNodes();
// }
// },

// _startObservingDistributedNodes: function() {
// this._distributedObservers = [];
// var root = this.getOwnerRoot();
// var host = root && root.host;
// if (host) {
// var h = Polymer.dom(host)
// .observeChildren(this._scheduleDistributedNodesNotify);
// this._distributedObservers.push(h);
// }
// },

// _stopObservingDistributedNodes: function() {

// },

// _scheduleDistributedNodesNotify: function() {
// this._distributedNodesDebouncer =
// Polymer.Debounce(this._distributedNodesDebouncer,
// this._notifyObservers);
// this._distributedNodesDebouncer.context = this.node;
// Polymer.dom.addDebouncer(this._distributedNodesDebouncer);
// },
DomApi.MutationContent.prototype = Object.create(DomApi.Mutation.prototype);

Polymer.Base.extend(DomApi.MutationContent.prototype, {

addListener: function(callback, includeChanges) {
this._includeChanges = includeChanges;
var h = DomApi.Mutation.prototype.addListener.call(this, callback);
this._scheduleNotify();
return h;
},

notifyIfNeeded: function() {
if (this._hasListeners()) {
this._scheduleNotify();
}
},

_notify: function() {
var info = this._includeChanges ? this._calcChanges() : {};
if (info) {
info.target = this.node;
this._callListeners(info);
}
},

_calcChanges: function() {
var changes = {
addedNodes: [],
removedNodes: []
};
var o$ = this.node.__distributedNodes = this.node.__distributedNodes ||
[];
var n$ = this.domApi.getDistributedNodes();
this.node.__distributedNodes = n$;
var splices = Polymer.ArraySplice.calculateSplices(n$, o$);
// process removals
for (var i=0, s; (i<splices.length) && (s=splices[i]); i++) {
for (var j=0, n; (j < s.removed.length) && (n=s.removed[j]); j++) {
changes.removedNodes.push(n);
}
}
// process adds
for (var i=0, s; (i<splices.length) && (s=splices[i]); i++) {
for (var j=s.index; j < s.index + s.addedCount; j++) {
changes.addedNodes.push(n$[j]);
}
}
if (changes.addedNodes.length || changes.removedNodes.length) {
return changes;
}
}

};
});

if (Settings.useShadow) {


Polymer.Base.extend(DomApi.MutationContent.prototype, {

_ensureObserver: function() {
var root = this.domApi.getOwnerRoot();
var host = root && root.host;
if (host) {
this._observer = Polymer.dom(host).observeNodes(
this.notifyIfNeeded.bind(this));
}
},

_cleanupObserver: function() {
if (this._observer) {
Polymer.dom(host).unobserveNodes(this._observer);
}
}

});


}

})();
Expand Down
Loading

0 comments on commit b11f86b

Please sign in to comment.