Skip to content

Commit

Permalink
fix(AttributeNode): Fixed issue where non strings wouldn't bind with …
Browse files Browse the repository at this point in the history
…bracket notation
  • Loading branch information
calebdwilliams committed Jan 6, 2018
1 parent f37e680 commit 6c4786a
Show file tree
Hide file tree
Showing 10 changed files with 241 additions and 218 deletions.
105 changes: 53 additions & 52 deletions dist/templiteral.cjs.js
Expand Up @@ -2,21 +2,23 @@


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


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


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


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


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


update(values) { 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 { class AttributeNode {
constructor(node, boundAttrs, boundEvents, context, index) { constructor(node, boundAttrs, boundEvents, context, compiler) {
this.node = node; this.node = node;
this.boundAttrs = boundAttrs; this.boundAttrs = boundAttrs;
this.boundEvents = boundEvents; this.boundEvents = boundEvents;
this.context = context; this.context = context;
this.index = index; this.compiler = compiler;
this.boundAttrs.forEach(attribute => attribute.base = attribute.value); 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(); this.addListeners();
} }


Expand All @@ -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) { updateProperty(attribute, attributeValue) {
const attributeName = attribute.name.replace(/\[|\]/g, ''); const attributeName = attribute.name.replace(/\[|\]/g, '');
this.node[attributeName] = attributeValue; this.node[attributeName] = attributeValue;
Expand All @@ -97,12 +93,21 @@ class AttributeNode {
const bases = attribute.base.match(/---!{*.}!---/g) || []; const bases = attribute.base.match(/---!{*.}!---/g) || [];
const baseIndicies = bases.map(base => +base.replace('---!{', '').replace('}!---', '')); const baseIndicies = bases.map(base => +base.replace('---!{', '').replace('}!---', ''));
let attributeValue = attribute.base; let attributeValue = attribute.base;
for (let i = 0; i < baseIndicies.length; i += 1) {
const value = values[baseIndicies[i]]; if (baseIndicies.length === 1) {
attributeValue = attributeValue.replace(`---!{${baseIndicies[i]}}!---`, value); 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; attribute.value = attributeValue;
if (attribute.name.match(propPattern)) { if (attribute.name.match(propPattern)) {
if (baseIndicies.length === 1) {
attributeValue = values[baseIndicies[0]];
}
this.updateProperty(attribute, attributeValue); this.updateProperty(attribute, attributeValue);
} }
}); });
Expand All @@ -117,19 +122,22 @@ class Template {
this.location = location; this.location = location;
this.context = context; this.context = context;
this.parts = []; this.parts = [];
this.templiteralParts = new Set(); this.partIndicies = new Map();

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


_append(node) { _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) { if (part instanceof ContentNode) {
part.setValue(this.values[index], this.oldValues[index]); part.setValue(this.values, this.oldValues[i]);
} else if (part instanceof AttributeNode) { } else if (part instanceof AttributeNode) {
part.update(this.values, this.oldValues); part.update(this.values, this.oldValues);
} }
}); }

this.location.appendChild(node); this.location.appendChild(node);
} }


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


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


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


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


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


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


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


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


exports.templiteral = templiteral; exports.templiteral = templiteral;
exports.registerElements = registerElements;
2 changes: 1 addition & 1 deletion dist/templiteral.cjs.min.js

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

0 comments on commit 6c4786a

Please sign in to comment.