Skip to content

Commit

Permalink
Merge pull request #4537 from Polymer/4536-kschaaf-hybrid-dom-bind
Browse files Browse the repository at this point in the history
Add 2.x hybrid affordances for stamping template content. Fixes #4536
  • Loading branch information
Steve Orvell authored Apr 17, 2017
2 parents f9bc452 + 9601065 commit 9dda1d4
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 37 deletions.
12 changes: 10 additions & 2 deletions src/lib/template/dom-bind.html
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,16 @@
},

_insertChildren: function() {
var parentDom = Polymer.dom(Polymer.dom(this).parentNode);
parentDom.insertBefore(this.root, this);
var refNode;
var parentNode = Polymer.dom(this).parentNode;
// Affordance for 2.x hybrid mode
if (parentNode.localName == this.is) {
refNode = parentNode;
parentNode = Polymer.dom(parentNode).parentNode;
} else {
refNode = this;
}
Polymer.dom(parentNode).insertBefore(this.root, refNode);
},

_removeChildren: function() {
Expand Down
25 changes: 18 additions & 7 deletions src/lib/template/dom-if.html
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,14 @@
},

detached: function() {
if (!this.parentNode ||
(this.parentNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE &&
var parentNode = this.parentNode;
if (parentNode && parentNode.localName == this.is) {
parentNode = Polymer.dom(parentNode).parentNode;
}
if (!parentNode ||
(parentNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE &&
(!Polymer.Settings.hasShadow ||
!(this.parentNode instanceof ShadowRoot)))) {
!(parentNode instanceof ShadowRoot)))) {
this._teardownInstance();
}
},
Expand Down Expand Up @@ -131,22 +135,29 @@
},

_ensureInstance: function() {
var refNode;
var parentNode = Polymer.dom(this).parentNode;
// Affordance for 2.x hybrid mode
if (parentNode && parentNode.localName == this.is) {
refNode = parentNode;
parentNode = Polymer.dom(parentNode).parentNode;
} else {
refNode = this;
}
// Guard against element being detached while render was queued
if (parentNode) {
var parent = Polymer.dom(parentNode);
if (!this._instance) {
this._instance = this.stamp();
var root = this._instance.root;
parent.insertBefore(root, this);
Polymer.dom(parentNode).insertBefore(root, refNode);
} else {
var c$ = this._instance._children;
if (c$ && c$.length) {
// Detect case where dom-if was re-attached in new position
var lastChild = Polymer.dom(this).previousSibling;
var lastChild = Polymer.dom(refNode).previousSibling;
if (lastChild !== c$[c$.length-1]) {
for (var i=0, n; (i<c$.length) && (n=c$[i]); i++) {
parent.insertBefore(n, this);
Polymer.dom(parentNode).insertBefore(n, refNode);
}
}
}
Expand Down
24 changes: 20 additions & 4 deletions src/lib/template/dom-repeat.html
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,18 @@
// only perform attachment if the element was previously detached.
if (this.__isDetached) {
this.__isDetached = false;
var parent = Polymer.dom(Polymer.dom(this).parentNode);
var refNode;
var parentNode = Polymer.dom(this).parentNode;
// Affordance for 2.x hybrid mode
if (parentNode.localName == this.is) {
refNode = parentNode;
parentNode = Polymer.dom(parentNode).parentNode;
} else {
refNode = this;
}
var parent = Polymer.dom(parentNode);
for (var i=0; i<this._instances.length; i++) {
this._attachInstance(i, parent);
this._attachInstance(i, parent, refNode);
}
}
},
Expand Down Expand Up @@ -666,10 +675,10 @@
}
},

_attachInstance: function(idx, parent) {
_attachInstance: function(idx, parent, refNode) {
var inst = this._instances[idx];
if (!inst.isPlaceholder) {
parent.insertBefore(inst.root, this);
parent.insertBefore(inst.root, refNode);
}
},

Expand Down Expand Up @@ -710,6 +719,13 @@
var beforeRow = this._instances[idx + 1];
var beforeNode = beforeRow && !beforeRow.isPlaceholder ? beforeRow._children[0] : this;
var parentNode = Polymer.dom(this).parentNode;
// Affordance for 2.x hybrid mode
if (parentNode.localName == this.is) {
if (beforeNode == this) {
beforeNode = parentNode;
}
parentNode = Polymer.dom(parentNode).parentNode;
}
Polymer.dom(parentNode).insertBefore(inst.root, beforeNode);
this._instances[idx] = inst;
return inst;
Expand Down
37 changes: 35 additions & 2 deletions test/unit/dom-bind.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
</template>

<script>
/* global earlyDomBind earlyBoundChild decEl1 decEl2 decDomBind z container needsHost*/
/* global earlyDomBind earlyBoundChild decEl1 decEl2 decDomBind z container needsHost hybridDomBind hybridEl1 hybridEl2*/
earlyDomBind.value = 'hi!';
</script>

Expand All @@ -42,6 +42,13 @@
<x-needs-host id="needsHost"></x-needs-host>
</template>

<dom-bind>
<template is="dom-bind" id="hybridDomBind">
<x-basic value="{{value}}" id="hybridEl1"></x-basic>
<x-basic value="{{value}}" id="hybridEl2"></x-basic>
</template>
</dom-bind>

<script>

suite('dom-bind touched before upgrade', function() {
Expand Down Expand Up @@ -235,7 +242,7 @@
Polymer.Settings.suppressTemplateNotifications ? 0 : 1);
done();
});
});
});

test('re-enable dom-change', function(done) {
if (Polymer.Settings.suppressTemplateNotifications) {
Expand All @@ -255,6 +262,32 @@

});

suite('hybrid dom-bind', function() {

var domBind;
var el1;
var el2;

setup(function() {
domBind = hybridDomBind;
el1 = hybridEl1;
el2 = hybridEl2;
});

test('value binds top-down', function() {
domBind.value = 'foo';
assert.equal(el1.value, 'foo');
assert.equal(el2.value, 'foo');
});

test('parent is parent of <dom-bind>', function() {
domBind.value = 'foo';
assert.equal(el1.parentNode, document.body);
assert.equal(el2.parentNode, document.body);
});

});

</script>

<link rel="import" href="dom-bind-elements2.html">
Expand Down
57 changes: 50 additions & 7 deletions test/unit/dom-if.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,51 @@
<template is="dom-if" if id="toBeRemoved"><div id="shouldBeRemoved"></div></template>
</div>

<!-- 2.x hybrid test -->
<dom-if id="hybridDomIfWrapper">
<template is="dom-if" id="hybridDomIf" if restamp>
<div hybrid-stamped>[[prop]]</div>
</template>
</dom-if>

<script>
/* global configured individual unconfigured1 unconfigured2 inDocumentContainer inDocumentIf structuredContainer structuredDomIf structuredDomBind outerContainer innerContainer shouldBeRemoved toBeRemoved removalContainer*/
/* global configured individual unconfigured1 unconfigured2 inDocumentContainer inDocumentIf structuredContainer structuredDomIf structuredDomBind outerContainer innerContainer shouldBeRemoved toBeRemoved removalContainer hybridDomIf hybridDomIfWrapper*/

suite('hybrid dom-if', function() {

test('parent is parent of <dom-if>', function() {
var stamped = [].slice.call(document.querySelectorAll('[hybrid-stamped]'));
assert.equal(stamped.length, 1);
assert.equal(stamped[0].parentNode, document.body);
});

test('remove & re-add works correctly', function(done) {
var wrapper = hybridDomIfWrapper;
var domIf = hybridDomIf;
Polymer.dom(document.body).removeChild(wrapper);
CustomElements.takeRecords();
domIf.render();
var stamped = [].slice.call(document.querySelectorAll('[hybrid-stamped]'));
assert.equal(stamped.length, 0);
Polymer.dom(removalContainer).appendChild(wrapper);
CustomElements.takeRecords();
setTimeout(function() {
stamped = [].slice.call(document.querySelectorAll('[hybrid-stamped]'));
assert.equal(stamped.length, 1);
assert.equal(stamped[0].parentNode, removalContainer);
done();
});
});

test('children removed correctly', function() {
hybridDomIf.if = false;
hybridDomIf.render();
var stamped = [].slice.call(document.querySelectorAll('[hybrid-stamped]'));
assert.equal(stamped.length, 0);
});

});

suite('nested pre-configured dom-if', function() {

test('parent scope binding', function() {
Expand Down Expand Up @@ -337,7 +380,7 @@
var stamped = Polymer.dom(unconfigured1.root).querySelectorAll('*:not(template):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
stamped[0].prop = 'outer';
assert.equal(unconfigured1.domUpdateHandlerCount,
assert.equal(unconfigured1.domUpdateHandlerCount,
Polymer.Settings.suppressTemplateNotifications ? 0 : 1);
});

Expand All @@ -352,7 +395,7 @@
stamped.forEach(function(n) {
assert.equal(getComputedStyle(n).display, 'none', 'node was not hidden but should have been');
});
assert.equal(unconfigured1.domUpdateHandlerCount,
assert.equal(unconfigured1.domUpdateHandlerCount,
Polymer.Settings.suppressTemplateNotifications ? 0 : 1);
});

Expand All @@ -368,7 +411,7 @@
stamped.forEach(function(n) {
assert.equal(getComputedStyle(n).display, 'inline', 'node was hidden but should not have been');
});
assert.equal(unconfigured1.domUpdateHandlerCount,
assert.equal(unconfigured1.domUpdateHandlerCount,
Polymer.Settings.suppressTemplateNotifications ? 0 : 1);
});

Expand All @@ -380,10 +423,10 @@
CustomElements.takeRecords();
CustomElements.takeRecords();
var stamped = Polymer.dom(unconfigured1.root).querySelectorAll('*:not(template)');
assert.equal(unconfigured1.domUpdateHandlerCount,
assert.equal(unconfigured1.domUpdateHandlerCount,
Polymer.Settings.suppressTemplateNotifications ? 0 : 1);
assert.equal(stamped.length, 0, 'total stamped count incorrect');
assert.equal(unconfigured1.domUpdateHandlerCount,
assert.equal(unconfigured1.domUpdateHandlerCount,
Polymer.Settings.suppressTemplateNotifications ? 0 : 1);
});

Expand All @@ -398,7 +441,7 @@
var stamped = Polymer.dom(unconfigured1.root).querySelectorAll('*:not(template):not(span)');
assert.equal(stamped.length, 3, 'total stamped count incorrect');
stamped[0].prop = 'outer';
assert.equal(unconfigured1.domUpdateHandlerCount,
assert.equal(unconfigured1.domUpdateHandlerCount,
Polymer.Settings.suppressTemplateNotifications ? 0 : 1);
});

Expand Down
Loading

0 comments on commit 9dda1d4

Please sign in to comment.