Permalink
Browse files

fix(AttributeNode): Fixed issue where non strings wouldn't bind with …

…bracket notation
  • Loading branch information...
calebdwilliams committed Jan 6, 2018
1 parent f37e680 commit 6c4786ad2a04f63a1ff3596b73294a88fc72941d
@@ -2,21 +2,23 @@

Object.defineProperty(exports, '__esModule', { value: true });

const valuePattern = /---!\{.*\}!---/gi;
const valuePattern = /---!{.*?(}!---)/gi;
const eventPattern = /^\(.*\)$/gi;
const propPattern = /^\[.*\]$/;
const sanitizePattern = /^this\./;
const startSeparator = /---!\{/gi;
const endSeparator = /\}!---/gi;

class ContentNode {
constructor(node) {
constructor(node, compiler) {
this.node = node;
this.compiler = compiler;
this.base = node.nodeValue || '';
this.index = +this.base
.match(valuePattern)[0]
.replace(startSeparator, '')
.replace(endSeparator, '');
this.indicies = this.base
.match(valuePattern)
.map(index => +index.replace(startSeparator, '').replace(endSeparator, ''));

this.indicies.forEach(index => this.compiler.partIndicies.set(index, this));
}

set value(_value) {
@@ -29,24 +31,33 @@ class ContentNode {
return this.node.nodeValue;
}

setValue(value = '') {
this.node.nodeValue = this.base.replace(valuePattern, value);
setValue(values = []) {
this.node.nodeValue = this.base.replace(/---!{*.}!---/g, (match) =>
values[+match.replace(startSeparator, '').replace(endSeparator, '')]
);
}

update(values) {
this.value = values[this.index];
this.node.nodeValue = this.base.replace(/---!{*.}!---/g, match => {
const value = values[+match.replace(startSeparator, '').replace(endSeparator, '')];
return value === null ? '' : value;
});
}
}

class AttributeNode {
constructor(node, boundAttrs, boundEvents, context, index) {
constructor(node, boundAttrs, boundEvents, context, compiler) {
this.node = node;
this.boundAttrs = boundAttrs;
this.boundEvents = boundEvents;
this.context = context;
this.index = index;
this.boundAttrs.forEach(attribute => attribute.base = attribute.value);

this.compiler = compiler;
this.boundAttrs.forEach(attribute => {
attribute.base = attribute.value;
this.indicies = attribute.base.match(valuePattern).map(index => +index.replace(startSeparator, '').replace(endSeparator, ''));
this.indicies.forEach(index => this.compiler.partIndicies.set(index, this));
});

this.addListeners();
}

@@ -67,21 +78,6 @@ class AttributeNode {
});
}

cleanUp() {
this.boundAttrs.forEach(attr =>
attr.value = attr.value.replace(startSeparator, '').replace(endSeparator, ''));
}

updateAttributes(name, newAttr) {
const attributeName = name.slice(1, -1);
if (newAttr.value) {
this.node[attributeName] = newAttr.value;
this.node.setAttribute(attributeName, newAttr.value);
} else {
this.node.removeAttribute(attributeName);
}
}

updateProperty(attribute, attributeValue) {
const attributeName = attribute.name.replace(/\[|\]/g, '');
this.node[attributeName] = attributeValue;
@@ -97,12 +93,21 @@ class AttributeNode {
const bases = attribute.base.match(/---!{*.}!---/g) || [];
const baseIndicies = bases.map(base => +base.replace('---!{', '').replace('}!---', ''));
let attributeValue = attribute.base;
for (let i = 0; i < baseIndicies.length; i += 1) {
const value = values[baseIndicies[i]];
attributeValue = attributeValue.replace(`---!{${baseIndicies[i]}}!---`, value);

if (baseIndicies.length === 1) {
attributeValue = attributeValue.replace(`---!{${baseIndicies[0]}}!---`, values[baseIndicies[0]]);
} else if (baseIndicies.length > 1) {
for (let i = 0; i < baseIndicies.length; i += 1) {
const value = values[baseIndicies[i]] || '';
attributeValue = attributeValue.replace(`---!{${baseIndicies[i]}}!---`, value);
}
}

attribute.value = attributeValue;
if (attribute.name.match(propPattern)) {
if (baseIndicies.length === 1) {
attributeValue = values[baseIndicies[0]];
}
this.updateProperty(attribute, attributeValue);
}
});
@@ -117,19 +122,22 @@ class Template {
this.location = location;
this.context = context;
this.parts = [];
this.templiteralParts = new Set();
this.partIndicies = new Map();

this.eventHandlers = [];
this._init();
}

_append(node) {
this.parts.forEach((part, index) => {
for (let i = 0; i < this.parts.length; i += 1) {
const part = this.parts[i];
if (part instanceof ContentNode) {
part.setValue(this.values[index], this.oldValues[index]);
part.setValue(this.values, this.oldValues[i]);
} else if (part instanceof AttributeNode) {
part.update(this.values, this.oldValues);
}
});
}

this.location.appendChild(node);
}

@@ -147,7 +155,6 @@ class Template {
}

_walk(walker, parts, setup) {
let index = -1;
while (walker.nextNode()) {
const { currentNode } = walker;
if (!currentNode.__templiteralCompiler) {
@@ -169,18 +176,15 @@ class Template {
}
}
if (boundAttrs.size >= 1 || boundEvents.size >= 1) {
index += 1;
const attrNode = new AttributeNode(currentNode, boundAttrs, boundEvents, this.context, index);
const attrNode = new AttributeNode(currentNode, boundAttrs, boundEvents, this.context, this);
parts.push(attrNode);
}
}
break;
}
case 3: {
index += 1;
if (currentNode.textContent && currentNode.textContent.match(valuePattern)) {
index += 1;
const contentNode = new ContentNode(currentNode, index);
const contentNode = new ContentNode(currentNode, this);
parts.push(contentNode);
}
break;
@@ -190,16 +194,17 @@ class Template {
this.templiteralParts.add(currentNode);
}
}
return parts;
}

update(values) {
this.oldValues = this.values;
this.values = values;

this.parts.forEach((part) => {
part.update(values, this.oldValues);
});
for (let i = 0; i < values.length; i += 1) {
if (values[i] !== this.oldValues[i]) {
this.partIndicies.get(i).update(values);
}
}
}
}

@@ -209,7 +214,7 @@ function templiteral(location = this, context = this) {
location.shadowRoot ? location = location.shadowRoot : null;

return (strings, ...values) => {
const templateKey = btoa(strings.join(''));
const templateKey = (strings.join(''));
let compiler = templateCache.get(templateKey);

if (compiler) {
@@ -218,13 +223,9 @@ function templiteral(location = this, context = this) {
compiler = new Template(strings, values, location, context);
templateCache.set(templateKey, compiler);
}
};
}

function registerElements(elements) {
elements.forEach(elementClass =>
customElements.define(elementClass.tagName, elementClass));
return compiler;
};
}

exports.templiteral = templiteral;
exports.registerElements = registerElements;

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
Oops, something went wrong.

0 comments on commit 6c4786a

Please sign in to comment.