Skip to content

Commit

Permalink
replaces before creating the elements (#322)
Browse files Browse the repository at this point in the history
* replaces before creating the elements

I also built the project and added tests

* version bump

* no longer modifying the original template
  • Loading branch information
e111077 committed Jun 17, 2016
1 parent 1916f1c commit 1aff4fb
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 73 deletions.
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"stacky": "^1.3.0",
"test-fixture": "polymerelements/test-fixture#^1.0.0"
},
"version": "4.2.2",
"version": "4.3.0",
"devDependencies": {
"polymer": "Polymer/polymer#^1.5.0",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.22"
Expand Down
113 changes: 86 additions & 27 deletions browser.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion browser.js.map

Large diffs are not rendered by default.

102 changes: 72 additions & 30 deletions browser/mocha/replace.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,42 +32,84 @@ extendInterfaces('replace', function(context, teardown) {
return;
}

// Keep a reference to the original `Polymer.Base.instanceTemplate`
// implementation for later:
var originalInstanceTemplate = Polymer.Base.instanceTemplate;

// Use Sinon to stub `Polymer.Base.instanceTemplate`:
sinon.stub(Polymer.Base, 'instanceTemplate', function(template) {
// The DOM to replace is the result of calling the "original"
// `instanceTemplate` implementation:
var dom = originalInstanceTemplate.apply(this, arguments);
var nodeIterator = document.createNodeIterator(dom,
NodeFilter.SHOW_ELEMENT);
var node;

// Traverses the tree. A recently-replaced node will be put next, so
// if a node is replaced, it will be checked if it needs to be
// replaced again.
while (node = nodeIterator.nextNode()) {
var currentTagName = node.tagName.toLowerCase();

if (replacements.hasOwnProperty(currentTagName)) {
// Create a replacement:
var replacement = document.createElement(
replacements[currentTagName]);

// For all attributes in the original node..
for (var index = 0; index < node.attributes.length; ++index) {
// Set that attribute on the replacement:
replacement.setAttribute(
node.attributes[index].name, node.attributes[index].value);
// dom to be replaced. _content is used for templatize calls the
// content is used for every other occasion of template instantiation
var dom = template._content || template.content;
var templateNode = dom;
var instanceNode;
var instanceParent;

// Traverses the tree. And places the new nodes (after replacing) into
// a new template.
while (templateNode) {
if (templateNode.nodeType === Node.ELEMENT_NODE) {
var originalTagName = templateNode.tagName.toLowerCase();
var currentTagName = originalTagName;

// determines the name of the element in the new template
while (replacements.hasOwnProperty(currentTagName)) {
currentTagName = replacements[currentTagName];
}

// if we have not changed this element, copy it over
if (currentTagName === originalTagName) {
instanceNode = document.importNode(templateNode);

} else {
// create the new node
instanceNode = document.createElement(currentTagName);

var numAttributes = templateNode.attributes.length;
// For all attributes in the original node..
for (var index=0; index<numAttributes; ++index) {
// Set that attribute on the new node:
instanceNode.setAttribute(templateNode.attributes[index].name,
templateNode.attributes[index].value);
}
}

} else {
// if it is not an element node, simply import it.
instanceNode = document.importNode(templateNode);
}

if (instanceParent) {
instanceParent.appendChild(instanceNode);
}

// traverse down the tree
if (templateNode.firstChild) {
instanceParent = instanceNode;
templateNode = templateNode.firstChild;

// traverse laterally if you cannot traverse down
} else if (templateNode.nextSibling) {
templateNode = templateNode.nextSibling;

// if the parent is the dom, we are done
} else if (templateNode.parentNode === dom) {
instanceParent = instanceNode.parentNode;
return instanceParent;

// traverse up
} else {
// traverse up until you can move laterally
while (!templateNode.nextSibling) {
templateNode = templateNode.parentNode;
instanceParent = instanceParent.parentNode;

// stop traversing up if we are at the top
if (templateNode === dom) {
return instanceParent;
}
}

// Replace the original node with the replacement node:
node.parentNode.replaceChild(replacement, node);
// traverse laterally
templateNode = templateNode.nextSibling;
}
}
return dom;
});

// After each test...
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "web-component-tester",
"version": "4.2.2",
"version": "4.3.0",
"description": "web-component-tester makes testing your web components a breeze!",
"keywords": [
"browser",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@

<link rel="import" href="normal-element.html">
<link rel="import" href="exception-element.html">

<dom-module id="dom-if-element">
<template>
<normal-element id="outside"></normal-element>

<template is="dom-if" if="{{isStamped}}">
<normal-element id="inside"></normal-element>
<exception-element id="inside"></exception-element>
</template>
</template>

Expand Down
13 changes: 13 additions & 0 deletions test/fixtures/integration/multiple-replace/exception-element.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<dom-module id="exception-element">
<template>
</template>
<script>
Polymer({
is: 'exception-element',

created: function() {
throw new Error('exception-element created');
}
});
</script>
</dom-module>
15 changes: 15 additions & 0 deletions test/fixtures/integration/multiple-replace/exception-fixture.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<link rel="import" href="normal-element.html">
<link rel="import" href="exception-element.html">

<dom-module id="exception-fixture">
<template>
<normal-element id="normal"></normal-element>
<exception-element id="exception"></exception-element>
</template>

<script>
Polymer({
is: 'exception-fixture'
});
</script>
</dom-module>
Loading

0 comments on commit 1aff4fb

Please sign in to comment.