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') {
|
||||
this.write(node);
|
||||
return;
|
||||
} else if (isArray(node) || (node instanceof Container)) {
|
||||
} else if (isArray(node)) {
|
||||
node.forEach(this.generateCode, this);
|
||||
return;
|
||||
} else if (node instanceof Container) {
|
||||
node.forEach((child) => {
|
||||
if (child.container === node) {
|
||||
this.generateCode(child);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let oldCurrentNode = this._currentNode;
|
||||
|
||||
@ -29,7 +29,7 @@ class ArrayContainer extends Container {
|
||||
var curChild = array[i];
|
||||
if (curChild === oldChild) {
|
||||
array[i] = newChild;
|
||||
oldChild.container = null;
|
||||
oldChild.detach();
|
||||
newChild.container = this;
|
||||
return true;
|
||||
}
|
||||
@ -42,8 +42,11 @@ class ArrayContainer extends Container {
|
||||
var childIndex = this.array.indexOf(child);
|
||||
if (childIndex !== -1) {
|
||||
this.array.splice(childIndex, 1);
|
||||
child.detach();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
child.container = null;
|
||||
}
|
||||
|
||||
prependChild(newChild) {
|
||||
@ -54,6 +57,7 @@ class ArrayContainer extends Container {
|
||||
|
||||
appendChild(newChild) {
|
||||
ok(newChild, 'Invalid child');
|
||||
newChild.detach();
|
||||
this.array.push(newChild);
|
||||
newChild.container = this;
|
||||
}
|
||||
@ -92,6 +96,20 @@ class ArrayContainer extends Container {
|
||||
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) {
|
||||
if (node.container !== this) {
|
||||
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) {
|
||||
var container = this.container;
|
||||
|
||||
@ -146,6 +153,7 @@ class Node {
|
||||
detach() {
|
||||
if (this.container) {
|
||||
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