Reputation: 65143
Le Code: http://jsfiddle.net/frf7w/12/
So right now, the current method will take the selected text exactly as... selected, and add tags so that when it is displayed, the page doesn't blow up.
But what I want to do: Is to, when a user selects a portion of a page, if there are un-matched tags within the selection, the selection will either jump forward or backward (depending on what unmatched tag is in the selection) to the tag(s) that make the selection valid html.
The reason why I want to do this, is because I want a user to be able te select text on a page, and be able to edit that text in a WYSIWYG editor (I can currently do this with the linked code), and then put what they've edited back into the page (currently can't do this, because the method I use adds tags).
Upvotes: 5
Views: 1637
Reputation: 9664
The coverAll
method in this SO answer has exactly what you want Use javascript to extend a DOM Range to cover partially selected nodes. For some reason extending Selection
prototype does not work for me on my chrome, so I extracted the code and substituted this
with window.getSelection()
. Final code looks like this:
function coverAll() {
var ranges = [];
for(var i=0; i<window.getSelection().rangeCount; i++) {
var range = window.getSelection().getRangeAt(i);
while(range.startContainer.nodeType == 3
|| range.startContainer.childNodes.length == 1)
range.setStartBefore(range.startContainer);
while(range.endContainer.nodeType == 3
|| range.endContainer.childNodes.length == 1)
range.setEndAfter(range.endContainer);
ranges.push(range);
}
window.getSelection().removeAllRanges();
for(var i=0; i<ranges.length; i++) {
window.getSelection().addRange(ranges[i]);
}
return;
}
Upvotes: 3
Reputation: 2839
You can change the boundaries of the selection by adding a range:
var sel = window.getSelection(),
range = sel.getRangeAt(0);
var startEl = sel.anchorNode;
if (startEl != range.commonAncestorContainer) {
while (startEl.parentNode != range.commonAncestorContainer) {
startEl = startEl.parentNode;
}
}
var endEl = sel.focusNode;
if (endEl != range.commonAncestorContainer) {
while (endEl.parentNode != range.commonAncestorContainer) {
endEl = endEl.parentNode;
}
}
range.setStartBefore(startEl);
range.setEndAfter(endEl);
sel.addRange(range);
The above example will give you a selection that is expanded to cover the entire of the tree between the start and end nodes, inclusive (thanks to commonAncestorContainer()
).
This treats text nodes as equal to dom elements, but this shouldn't be a problem for you.
Demo: http://jsfiddle.net/Nq6hr/2/
Upvotes: 2
Reputation: 3392
You should work with the nodes given by the selection. It seems extentNode and anchorNode represents the end and the beginning of nodes of the selection both can help you having the "full" selection. https://developer.mozilla.org/fr/DOM/Selection
For the inline editing you should give a try to contentEditable attribute. You can surround the elements of your selection with a span containing this attribute https://developer.mozilla.org/en/DOM/element.contentEditable
Upvotes: 0