lit-html
Advanced tools
Comparing version 0.2.1 to 0.2.2
@@ -108,7 +108,9 @@ /** | ||
const attributeString = this._strings[partIndex]; | ||
partIndex += strings.length - 1; | ||
const match = attributeString.match(/((?:\w|[.\-_])+)=?("|')?$/); | ||
// Trim the trailing literal value if this is an interpolation | ||
const rawNameString = attributeString.substring(0, attributeString.length - strings[0].length); | ||
const match = rawNameString.match(/((?:\w|[.\-_$])+)=["']?$/); | ||
const rawName = match[1]; | ||
this.parts.push(new TemplatePart('attribute', index, attribute.name, rawName, strings)); | ||
attributesToRemove.push(attribute); | ||
partIndex += strings.length - 1; | ||
} | ||
@@ -136,3 +138,2 @@ } | ||
nodesToRemove.push(node); | ||
index--; | ||
} | ||
@@ -252,17 +253,28 @@ } | ||
let next = values.next(); | ||
if (current.done) { | ||
// Empty iterable, just clear | ||
this.clear(); | ||
} | ||
while (!current.done) { | ||
if (next.done) { | ||
// on the last item, reuse this part's endNode | ||
itemEnd = this.endNode; | ||
} | ||
else { | ||
itemEnd = new Text(); | ||
this.endNode.parentNode.insertBefore(itemEnd, this.endNode); | ||
} | ||
// Reuse a part if we can, otherwise create a new one | ||
// Reuse a previous part if we can, otherwise create a new one | ||
let itemPart; | ||
if (previousParts !== undefined && previousPartsIndex < previousParts.length) { | ||
itemPart = previousParts[previousPartsIndex++]; | ||
if (next.done && itemPart.endNode !== this.endNode) { | ||
// Since this is the last part we'll use, set it's endNode to the | ||
// container's endNode. Setting the value of this part will clean | ||
// up any residual nodes from a previously longer iterable. | ||
itemPart.endNode = this.endNode; | ||
} | ||
itemEnd = itemPart.endNode; | ||
} | ||
else { | ||
if (next.done) { | ||
// on the last item, reuse this part's endNode | ||
itemEnd = this.endNode; | ||
} | ||
else { | ||
itemEnd = new Text(); | ||
this.endNode.parentNode.insertBefore(itemEnd, this.endNode); | ||
} | ||
itemPart = new NodePart(itemStart, itemEnd); | ||
@@ -277,17 +289,2 @@ } | ||
this._previousValue = itemParts; | ||
// If the new list is shorter than the old list, clean up: | ||
if (previousParts !== undefined && previousPartsIndex < previousParts.length) { | ||
const clearStart = previousParts[previousPartsIndex].startNode; | ||
const clearEnd = previousParts[previousParts.length - 1].endNode; | ||
const clearRange = document.createRange(); | ||
if (previousPartsIndex === 0) { | ||
clearRange.setStartBefore(clearStart); | ||
} | ||
else { | ||
clearRange.setStartAfter(clearStart); | ||
} | ||
clearRange.setEndAfter(clearEnd); | ||
clearRange.deleteContents(); | ||
clearRange.detach(); // is this neccessary? | ||
} | ||
} | ||
@@ -304,9 +301,7 @@ else { | ||
this._previousValue = undefined; | ||
let node = this.startNode; | ||
let next = node.nextSibling; | ||
while (next !== null && next !== this.endNode) { | ||
node = next; | ||
next = next.nextSibling; | ||
node.parentNode.removeChild(node); | ||
} | ||
const range = document.createRange(); | ||
range.setStartAfter(this.startNode); | ||
range.setEndBefore(this.endNode); | ||
range.deleteContents(); | ||
range.detach(); | ||
} | ||
@@ -313,0 +308,0 @@ } |
@@ -160,3 +160,3 @@ /** | ||
}); | ||
test('renders to an attribute and node', () => { | ||
test('renders to an attribute before a node', () => { | ||
const container = document.createElement('div'); | ||
@@ -166,2 +166,7 @@ html `<div foo="${'bar'}">${'baz'}</div>`.renderTo(container); | ||
}); | ||
test('renders to an attribute after a node', () => { | ||
const container = document.createElement('div'); | ||
html `<div>${'baz'}</div><div foo="${'bar'}"></div>`.renderTo(container); | ||
assert.equal(container.innerHTML, '<div>baz</div><div foo="bar"></div>'); | ||
}); | ||
test('renders a combination of stuff', () => { | ||
@@ -377,3 +382,11 @@ const container = document.createElement('div'); | ||
assert.equal(container.innerHTML, '123'); | ||
assert.strictEqual(container.firstChild, startNode); | ||
assert.strictEqual(container.lastChild, endNode); | ||
}); | ||
test('accepts an empty array', () => { | ||
part.setValue([]); | ||
assert.equal(container.innerHTML, ''); | ||
assert.strictEqual(container.firstChild, startNode); | ||
assert.strictEqual(container.lastChild, endNode); | ||
}); | ||
test('accepts nested templates', () => { | ||
@@ -405,9 +418,34 @@ part.setValue(html `<h1>${'foo'}</h1>`); | ||
assert.equal(container.innerHTML, '123'); | ||
assert.deepEqual(['', '1', '', '2', '', '3', ''], Array.from(container.childNodes).map((n) => n.nodeValue)); | ||
assert.strictEqual(container.firstChild, startNode); | ||
assert.strictEqual(container.lastChild, endNode); | ||
const n2 = container.childNodes.item(2); | ||
const n4 = container.childNodes.item(4); | ||
part.setValue([]); | ||
assert.equal(container.innerHTML, ''); | ||
assert.deepEqual(['', ''], Array.from(container.childNodes).map((n) => n.nodeValue)); | ||
assert.strictEqual(container.firstChild, startNode); | ||
assert.strictEqual(container.lastChild, endNode); | ||
}); | ||
test('updates when called multiple times with arrays', () => { | ||
part.setValue([1, 2, 3]); | ||
assert.equal(container.innerHTML, '123'); | ||
assert.deepEqual(['', '1', '', '2', '', '3', ''], Array.from(container.childNodes).map((n) => n.nodeValue)); | ||
assert.strictEqual(container.firstChild, startNode); | ||
assert.strictEqual(container.lastChild, endNode); | ||
part.setValue([4, 5]); | ||
assert.equal(container.innerHTML, '45'); | ||
// check that we're not leaving orphaned marker nodes around | ||
assert.deepEqual(['', '4', '', '5', ''], Array.from(container.childNodes).map((n) => n.nodeValue)); | ||
assert.strictEqual(container.firstChild, startNode); | ||
assert.strictEqual(container.lastChild, endNode); | ||
part.setValue([]); | ||
assert.equal(container.innerHTML, ''); | ||
assert.deepEqual([], Array.from(container.childNodes).map((n) => n.nodeValue)); | ||
assert.deepEqual(['', ''], Array.from(container.childNodes).map((n) => n.nodeValue)); | ||
assert.strictEqual(container.firstChild, startNode); | ||
assert.strictEqual(container.lastChild, endNode); | ||
part.setValue([4, 5]); | ||
assert.equal(container.innerHTML, '45'); | ||
assert.deepEqual(['', '4', '', '5', ''], Array.from(container.childNodes).map((n) => n.nodeValue)); | ||
assert.strictEqual(container.firstChild, startNode); | ||
assert.strictEqual(container.lastChild, endNode); | ||
}); | ||
@@ -414,0 +452,0 @@ test('updates are stable when called multiple times with templates', () => { |
{ | ||
"name": "lit-html", | ||
"version": "0.2.1", | ||
"version": "0.2.2", | ||
"description": "HTML template literals in JavaScript", | ||
@@ -5,0 +5,0 @@ "license": "BSD-3-Clause", |
@@ -123,7 +123,9 @@ /** | ||
const attributeString = this._strings[partIndex]; | ||
partIndex += strings.length - 1; | ||
const match = attributeString.match(/((?:\w|[.\-_])+)=?("|')?$/); | ||
// Trim the trailing literal value if this is an interpolation | ||
const rawNameString = attributeString.substring(0, attributeString.length - strings[0].length); | ||
const match = rawNameString.match(/((?:\w|[.\-_$])+)=["']?$/); | ||
const rawName = match![1]; | ||
this.parts.push(new TemplatePart('attribute', index, attribute.name, rawName, strings)); | ||
attributesToRemove.push(attribute); | ||
partIndex += strings.length - 1; | ||
} | ||
@@ -150,6 +152,6 @@ } | ||
nodesToRemove.push(node); | ||
index--; | ||
} | ||
} | ||
} | ||
// Remove text binding nodes after the walk to not disturb the TreeWalker | ||
@@ -283,3 +285,3 @@ for (const n of nodesToRemove) { | ||
const previousParts = Array.isArray(this._previousValue) ? this._previousValue : undefined; | ||
const previousParts: NodePart[]|undefined = Array.isArray(this._previousValue) ? this._previousValue : undefined; | ||
let previousPartsIndex = 0; | ||
@@ -290,16 +292,26 @@ const itemParts = []; | ||
if (current.done) { | ||
// Empty iterable, just clear | ||
this.clear(); | ||
} | ||
while (!current.done) { | ||
if (next.done) { | ||
// on the last item, reuse this part's endNode | ||
itemEnd = this.endNode; | ||
} else { | ||
itemEnd = new Text(); | ||
this.endNode.parentNode!.insertBefore(itemEnd, this.endNode); | ||
} | ||
// Reuse a part if we can, otherwise create a new one | ||
let itemPart; | ||
// Reuse a previous part if we can, otherwise create a new one | ||
let itemPart: NodePart; | ||
if (previousParts !== undefined && previousPartsIndex < previousParts.length) { | ||
itemPart = previousParts[previousPartsIndex++]; | ||
if (next.done && itemPart.endNode !== this.endNode) { | ||
// Since this is the last part we'll use, set it's endNode to the | ||
// container's endNode. Setting the value of this part will clean | ||
// up any residual nodes from a previously longer iterable. | ||
itemPart.endNode = this.endNode; | ||
} | ||
itemEnd = itemPart.endNode; | ||
} else { | ||
if (next.done) { | ||
// on the last item, reuse this part's endNode | ||
itemEnd = this.endNode; | ||
} else { | ||
itemEnd = new Text(); | ||
this.endNode.parentNode!.insertBefore(itemEnd, this.endNode); | ||
} | ||
itemPart = new NodePart(itemStart, itemEnd); | ||
@@ -316,18 +328,2 @@ } | ||
this._previousValue = itemParts; | ||
// If the new list is shorter than the old list, clean up: | ||
if (previousParts !== undefined && previousPartsIndex < previousParts.length) { | ||
const clearStart = previousParts[previousPartsIndex].startNode; | ||
const clearEnd = previousParts[previousParts.length - 1].endNode; | ||
const clearRange = document.createRange(); | ||
if (previousPartsIndex === 0) { | ||
clearRange.setStartBefore(clearStart); | ||
} else { | ||
clearRange.setStartAfter(clearStart); | ||
} | ||
clearRange.setEndAfter(clearEnd); | ||
clearRange.deleteContents(); | ||
clearRange.detach(); // is this neccessary? | ||
} | ||
} else { | ||
@@ -344,12 +340,9 @@ this.clear(); | ||
this._previousValue = undefined; | ||
let node: Node = this.startNode; | ||
let next: Node|null = node.nextSibling; | ||
while (next !== null && next !== this.endNode) { | ||
node = next; | ||
next = next.nextSibling; | ||
node.parentNode!.removeChild(node); | ||
} | ||
const range = document.createRange(); | ||
range.setStartAfter(this.startNode); | ||
range.setEndBefore(this.endNode); | ||
range.deleteContents(); | ||
range.detach(); | ||
} | ||
// detach(): DocumentFragment ? | ||
} | ||
@@ -356,0 +349,0 @@ |
@@ -192,3 +192,3 @@ /** | ||
test('renders to an attribute and node', () => { | ||
test('renders to an attribute before a node', () => { | ||
const container = document.createElement('div'); | ||
@@ -199,2 +199,8 @@ html`<div foo="${'bar'}">${'baz'}</div>`.renderTo(container); | ||
test('renders to an attribute after a node', () => { | ||
const container = document.createElement('div'); | ||
html`<div>${'baz'}</div><div foo="${'bar'}"></div>`.renderTo(container); | ||
assert.equal(container.innerHTML, '<div>baz</div><div foo="bar"></div>'); | ||
}); | ||
test('renders a combination of stuff', () => { | ||
@@ -460,4 +466,13 @@ const container = document.createElement('div'); | ||
assert.equal(container.innerHTML, '123'); | ||
assert.strictEqual(container.firstChild, startNode); | ||
assert.strictEqual(container.lastChild, endNode); | ||
}); | ||
test('accepts an empty array', () => { | ||
part.setValue([]); | ||
assert.equal(container.innerHTML, ''); | ||
assert.strictEqual(container.firstChild, startNode); | ||
assert.strictEqual(container.lastChild, endNode); | ||
}); | ||
test('accepts nested templates', () => { | ||
@@ -493,11 +508,39 @@ part.setValue(html`<h1>${'foo'}</h1>`); | ||
assert.equal(container.innerHTML, '123'); | ||
assert.deepEqual(['', '1', '', '2', '', '3', ''], Array.from(container.childNodes).map((n) => n.nodeValue)); | ||
assert.strictEqual(container.firstChild, startNode); | ||
assert.strictEqual(container.lastChild, endNode); | ||
const n2 = container.childNodes.item(2); | ||
const n4 = container.childNodes.item(4); | ||
part.setValue([]); | ||
assert.equal(container.innerHTML, ''); | ||
assert.deepEqual(['', ''], Array.from(container.childNodes).map((n) => n.nodeValue)); | ||
assert.strictEqual(container.firstChild, startNode); | ||
assert.strictEqual(container.lastChild, endNode); | ||
}); | ||
test('updates when called multiple times with arrays', () => { | ||
part.setValue([1, 2, 3]); | ||
assert.equal(container.innerHTML, '123'); | ||
assert.deepEqual(['', '1', '', '2', '', '3', ''], Array.from(container.childNodes).map((n) => n.nodeValue)); | ||
assert.strictEqual(container.firstChild, startNode); | ||
assert.strictEqual(container.lastChild, endNode); | ||
part.setValue([4, 5]); | ||
assert.equal(container.innerHTML, '45'); | ||
// check that we're not leaving orphaned marker nodes around | ||
assert.deepEqual(['', '4', '', '5', ''], Array.from(container.childNodes).map((n) => n.nodeValue)); | ||
assert.strictEqual(container.firstChild, startNode); | ||
assert.strictEqual(container.lastChild, endNode); | ||
part.setValue([]); | ||
assert.equal(container.innerHTML, ''); | ||
assert.deepEqual([], Array.from(container.childNodes).map((n) => n.nodeValue)); | ||
assert.deepEqual(['', ''], Array.from(container.childNodes).map((n) => n.nodeValue)); | ||
assert.strictEqual(container.firstChild, startNode); | ||
assert.strictEqual(container.lastChild, endNode); | ||
part.setValue([4, 5]); | ||
assert.equal(container.innerHTML, '45'); | ||
assert.deepEqual(['', '4', '', '5', ''], Array.from(container.childNodes).map((n) => n.nodeValue)); | ||
assert.strictEqual(container.firstChild, startNode); | ||
assert.strictEqual(container.lastChild, endNode); | ||
}); | ||
@@ -504,0 +547,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
163871
2481