mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
Marko v3: Better handling of detaching and moving child nodes
This commit is contained in:
parent
4b3c738a8d
commit
e576718d11
@ -162,9 +162,16 @@ class Generator {
|
|||||||
typeof node === 'boolean') {
|
typeof node === 'boolean') {
|
||||||
this.write(node);
|
this.write(node);
|
||||||
return;
|
return;
|
||||||
} else if (isArray(node) || (node instanceof Container)) {
|
} else if (isArray(node)) {
|
||||||
node.forEach(this.generateCode, this);
|
node.forEach(this.generateCode, this);
|
||||||
return;
|
return;
|
||||||
|
} else if (node instanceof Container) {
|
||||||
|
node.forEach((child) => {
|
||||||
|
if (child.container === node) {
|
||||||
|
this.generateCode(child);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let oldCurrentNode = this._currentNode;
|
let oldCurrentNode = this._currentNode;
|
||||||
|
|||||||
@ -29,7 +29,7 @@ class ArrayContainer extends Container {
|
|||||||
var curChild = array[i];
|
var curChild = array[i];
|
||||||
if (curChild === oldChild) {
|
if (curChild === oldChild) {
|
||||||
array[i] = newChild;
|
array[i] = newChild;
|
||||||
oldChild.container = null;
|
oldChild.detach();
|
||||||
newChild.container = this;
|
newChild.container = this;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -42,8 +42,11 @@ class ArrayContainer extends Container {
|
|||||||
var childIndex = this.array.indexOf(child);
|
var childIndex = this.array.indexOf(child);
|
||||||
if (childIndex !== -1) {
|
if (childIndex !== -1) {
|
||||||
this.array.splice(childIndex, 1);
|
this.array.splice(childIndex, 1);
|
||||||
|
child.detach();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
child.container = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prependChild(newChild) {
|
prependChild(newChild) {
|
||||||
@ -54,6 +57,7 @@ class ArrayContainer extends Container {
|
|||||||
|
|
||||||
appendChild(newChild) {
|
appendChild(newChild) {
|
||||||
ok(newChild, 'Invalid child');
|
ok(newChild, 'Invalid child');
|
||||||
|
newChild.detach();
|
||||||
this.array.push(newChild);
|
this.array.push(newChild);
|
||||||
newChild.container = this;
|
newChild.container = this;
|
||||||
}
|
}
|
||||||
@ -92,6 +96,20 @@ class ArrayContainer extends Container {
|
|||||||
throw new Error('Reference node not found');
|
throw new Error('Reference node not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moveChildrenTo(target) {
|
||||||
|
ok(target.appendChild, 'Node does not support appendChild(node): ' + target);
|
||||||
|
|
||||||
|
var array = this.array;
|
||||||
|
var len = array.length;
|
||||||
|
for (var i=0; i<len; i++) {
|
||||||
|
var curChild = array[i];
|
||||||
|
curChild.container = null; // Detach the child from this container
|
||||||
|
target.appendChild(curChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.array.length = 0; // Clear out this container
|
||||||
|
}
|
||||||
|
|
||||||
forEachNextSibling(node, callback, thisObj) {
|
forEachNextSibling(node, callback, thisObj) {
|
||||||
if (node.container !== this) {
|
if (node.container !== this) {
|
||||||
throw new Error('Node does not belong to container: ' + node);
|
throw new Error('Node does not belong to container: ' + node);
|
||||||
|
|||||||
@ -108,6 +108,13 @@ class Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moveChildrenTo(targetNode) {
|
||||||
|
ok(this.body, 'Node does not support child nodes: ' + this);
|
||||||
|
ok(this !== targetNode, 'Target node cannot be the same as the source node');
|
||||||
|
|
||||||
|
this.body.moveChildrenTo(targetNode);
|
||||||
|
}
|
||||||
|
|
||||||
forEachNextSibling(callback, thisObj) {
|
forEachNextSibling(callback, thisObj) {
|
||||||
var container = this.container;
|
var container = this.container;
|
||||||
|
|
||||||
@ -146,6 +153,7 @@ class Node {
|
|||||||
detach() {
|
detach() {
|
||||||
if (this.container) {
|
if (this.container) {
|
||||||
this.container.removeChild(this);
|
this.container.removeChild(this);
|
||||||
|
this.container = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
test/fixtures/codegen/autotest/moveChildrenTo/expected.js
vendored
Normal file
1
test/fixtures/codegen/autotest/moveChildrenTo/expected.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
out.w("<div></div><span>FooHello World</span>");
|
||||||
24
test/fixtures/codegen/autotest/moveChildrenTo/index.js
vendored
Normal file
24
test/fixtures/codegen/autotest/moveChildrenTo/index.js
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = function(builder) {
|
||||||
|
var div = builder.htmlElement(
|
||||||
|
'div',
|
||||||
|
[],
|
||||||
|
[
|
||||||
|
builder.text(builder.literal('Hello World'))
|
||||||
|
]);
|
||||||
|
|
||||||
|
var span = builder.htmlElement(
|
||||||
|
'span',
|
||||||
|
[],
|
||||||
|
[
|
||||||
|
builder.text(builder.literal('Foo'))
|
||||||
|
]);
|
||||||
|
|
||||||
|
div.moveChildrenTo(span);
|
||||||
|
|
||||||
|
return [
|
||||||
|
div,
|
||||||
|
span
|
||||||
|
];
|
||||||
|
};
|
||||||
Loading…
x
Reference in New Issue
Block a user