From 07261e4b8ef797b9916ced21b718390fe2a79c61 Mon Sep 17 00:00:00 2001
From: Steven Orvell
Date: Thu, 13 Aug 2015 15:31:29 -0700
Subject: [PATCH] Add `Polymer.dom().notifyObservers` method to 'kick'
observers, for example, when attributes change under Shadow DOM.
---
src/lib/dom-api-mutation-content.html | 4 +-
src/lib/dom-api-mutation.html | 18 +++-
src/lib/dom-api.html | 62 ++++---------
src/mini/shady.html | 34 ++++---
test/smoke/observeReNodes.html | 29 +++++-
test/smoke/observeReNodes2.html | 126 ++++++++++++++++++++++++++
6 files changed, 203 insertions(+), 70 deletions(-)
create mode 100644 test/smoke/observeReNodes2.html
diff --git a/src/lib/dom-api-mutation-content.html b/src/lib/dom-api-mutation-content.html
index bf13de0130..b603d91ca8 100644
--- a/src/lib/dom-api-mutation-content.html
+++ b/src/lib/dom-api-mutation-content.html
@@ -30,7 +30,7 @@
return h;
},
- notifyIfNeeded: function() {
+ notify: function() {
if (this._hasListeners()) {
this._scheduleNotify();
}
@@ -82,7 +82,7 @@
var host = root && root.host;
if (host) {
this._observer = Polymer.dom(host).observeNodes(
- this.notifyIfNeeded.bind(this));
+ this.notify.bind(this));
}
},
diff --git a/src/lib/dom-api-mutation.html b/src/lib/dom-api-mutation.html
index 5d0f6dc47c..1d3b16fd8f 100644
--- a/src/lib/dom-api-mutation.html
+++ b/src/lib/dom-api-mutation.html
@@ -14,6 +14,7 @@
var DomApi = Polymer.DomApi.ctor;
var Settings = Polymer.Settings;
+ var hasDomApi = Polymer.DomApi.hasDomApi;
DomApi.Mutation = function(domApi) {
this.domApi = domApi;
@@ -100,7 +101,7 @@
_observeContentElements: function(elements) {
for (var i=0, h, n; (i < elements.length) && (n=elements[i]); i++) {
- if (n.localName === 'content') {
+ if (this._isContent(n)) {
n.__observeNodesMap = n.__observeNodesMap || new WeakMap();
if (n.__observeNodesMap.get(this) === undefined) {
h = Polymer.dom(n).observeNodes(
@@ -113,7 +114,7 @@
_unobserveContentElements: function(elements) {
for (var i=0, n, h; (i < elements.length) && (n=elements[i]); i++) {
- if (n.localName === 'content') {
+ if (this._isContent(n)) {
h = n.__observeNodesMap.get(this);
if (h) {
Polymer.dom(n).unobserveNodes(h);
@@ -122,6 +123,10 @@
}
},
+ _isContent: function(node) {
+ return (node.localName === 'content');
+ },
+
_callListeners: function(info) {
var o$ = this._listeners;
for (var i=0, o; (i < o$.length) && (o=o$[i]); i++) {
@@ -151,10 +156,13 @@
this._debouncer.context = this;
Polymer.dom.addDebouncer(this._debouncer);
this._preflush = this._flush.bind(this);
- Polymer.dom.addPreflush(this._preflush);
+
+ }
+ if (!this._hasListeners()) {
+ Polymer.dom.addPreflush(this._preflush);
+ // note: doing this > 1x is a no-op
+ this._observer.observe(this.node, {childList: true});
}
- // note: doing this > 1x is a no-op
- this._observer.observe(this.node, {childList: true});
},
_cleanupObserver: function() {
diff --git a/src/lib/dom-api.html b/src/lib/dom-api.html
index 906ca167dc..91b8e92db2 100644
--- a/src/lib/dom-api.html
+++ b/src/lib/dom-api.html
@@ -538,7 +538,10 @@
if (this.observer) {
this.observer.removeListener(handle);
}
- }
+ },
+
+ // abstract, intended as public 'kick' mehanism
+ notifyObservers: function() {}
};
@@ -744,58 +747,25 @@
DomApi.prototype._distributeParent = function() {};
- DomApi.prototype.observeChildren = function(callback) {
- if (!this._mo) {
- this._mo = new MutationObserver(this._notifyObservers.bind(this));
- this._mo.observe(this.node, {childList: true});
- // make sure to notify initial state...
- this._mutationDebouncer = Polymer.Debounce(this._mutationDebouncer,
- function() {
- this._notifyObservers([{
- target: this.node,
- addedNodes: this.childNodes.slice()
- }]);
- }
- );
- this._mutationDebouncer.context = this;
- Polymer.dom.addDebouncer(this._mutationDebouncer);
- }
- return this._observers.push(callback);
- };
-
- DomApi.prototype._notifyObservers = function(mxns) {
- var info = {
- target: this.node,
- addedNodes: [],
- removedNodes: []
- };
- mxns.forEach(function(m) {
- if (m.addedNodes) {
- for (var i=0; i < m.addedNodes.length; i++) {
- info.addedNodes.push(m.addedNodes[i]);
+ DomApi.prototype.notifyObservers = function() {
+ if (this.node.shadowRoot) {
+ var ip$ = this.node.shadowRoot.querySelectorAll('content');
+ for (var i=0, c; (i
@@ -68,8 +78,8 @@
Polymer.dom.flush();
-
- // setTimeout(function() {
+
+ function test() {
console.group('test dynamic');
var d = makeNode('dynamic!');
Polymer.dom.flush();
@@ -91,7 +101,18 @@
Polymer.dom(content).removeChild(Polymer.dom(content).lastChild);
Polymer.dom.flush();
console.groupEnd('test dynamic');
- // }, 1000);
+ }
+ test();
+ content.$.inner.unobserve();
+ test();
+ content.$.inner.observe();
+ test();
+ content.$.inner.unobserve();
+ test();
+ content.$.inner.observe();
+ test();
+
+
+
+
+
+ ~~
+
+
+
+
+
+
+ []
+
+
+
+
+
+ content A
+ content B
+
+
+
+
+
+
+
diff --git a/test/smoke/observeReNodes2.html b/test/smoke/observeReNodes2.html
new file mode 100644
index 0000000000..e9477e1fc2
--- /dev/null
+++ b/test/smoke/observeReNodes2.html
@@ -0,0 +1,126 @@
+
+
+