M
matth
I've been working on something that deals with handling a user's
selection within the DOM and I'm tripping up on one last, but crucial,
detail.
Forgive me for the length of the code, but my question is pretty
straightforward and my brain hasn't been working.
Problem: The way I'm iterating through the nodes doesn't allow me to
preserve the node hierarchy.
Instead of:
<div></div><b></b>text
I want:
<div><b>text</b></div>
function RangeIterator() {
this.onNode = function (str, node) {
commonplaceLogMain.cplNodes += '<' + node.nodeName + '>' + str + '</'
+ node.nodeName + '>' ;
};
this.iterate = function (r) {
var me = this, node = r.startContainer, offset = r.startOffset,
finalNode = r.endContainer, finalOffset = r.endOffset;
function visitNode(node, offset) {
var isFinal = (node == finalNode), lastChildIndex, i, c, str = '';
switch (node.nodeType) {
case 3:
case 4:
case 7:
case 8:
str = node.nodeValue;
if (isFinal) {
str = str.substring(0, finalOffset);
}
if (offset) {
str = str.substring(offset);
}
me.onNode(str, node);
break;
default:
me.onNode(str, node);
lastChildIndex = isFinal ? finalOffset : node.childNodes.length;
for (i = offset, c = node.childNodes.item(i); i < lastChildIndex; c =
c.nextSibling, i++) {
if (!visitNode(c, 0)) {
return false;
}
}
}
return !isFinal;
}
while (visitNode(node, offset)) {
if (!node.nextSibling) {
node = node.parentNode;
offset = node.childNodes.length;
} else {
node = node.nextSibling;
offset = 0;
}
}
return true;
};
}
selection within the DOM and I'm tripping up on one last, but crucial,
detail.
Forgive me for the length of the code, but my question is pretty
straightforward and my brain hasn't been working.
Problem: The way I'm iterating through the nodes doesn't allow me to
preserve the node hierarchy.
Instead of:
<div></div><b></b>text
I want:
<div><b>text</b></div>
function RangeIterator() {
this.onNode = function (str, node) {
commonplaceLogMain.cplNodes += '<' + node.nodeName + '>' + str + '</'
+ node.nodeName + '>' ;
};
this.iterate = function (r) {
var me = this, node = r.startContainer, offset = r.startOffset,
finalNode = r.endContainer, finalOffset = r.endOffset;
function visitNode(node, offset) {
var isFinal = (node == finalNode), lastChildIndex, i, c, str = '';
switch (node.nodeType) {
case 3:
case 4:
case 7:
case 8:
str = node.nodeValue;
if (isFinal) {
str = str.substring(0, finalOffset);
}
if (offset) {
str = str.substring(offset);
}
me.onNode(str, node);
break;
default:
me.onNode(str, node);
lastChildIndex = isFinal ? finalOffset : node.childNodes.length;
for (i = offset, c = node.childNodes.item(i); i < lastChildIndex; c =
c.nextSibling, i++) {
if (!visitNode(c, 0)) {
return false;
}
}
}
return !isFinal;
}
while (visitNode(node, offset)) {
if (!node.nextSibling) {
node = node.parentNode;
offset = node.childNodes.length;
} else {
node = node.nextSibling;
offset = 0;
}
}
return true;
};
}