views:

76

answers:

3

Does any one know of any cross browser user selection range libraries written in javascript?

I have a found a few jquery plugins, (which quite frankly are too limiting and very buggy). I have already implemented and am using the following to pull off some of my tricks:

http://plugins.jquery.com/project/wrapSelection http://perplexed.co.uk/1020_text_selector_jquery_plugin.htm

And a few other small scripts and such.

I would just like to know what you have found out there. Don't send me googling this again, (I've spent days working on all this). Hopefully this can be where future programmers can find the answer.

+1  A: 

For general-purpose range work (as opposed to input/textarea selection handling), consider ierange. Attempts to implement the standard DOM Level 2 Range model supported by other browsers in IE. Kind-of works.

bobince
One of the main features I need is to surround a selection with a span. This code can do that but it doesn't handle wrapping a span around a selection that overlaps other end tags.
Dale
Well, such a thing would be impossible, of course! A span, like any element, must have a single parent. If you wanted to add a highlight to a stretch of text whose endpoints were not inside the same element, you would have to walk over each element in the selection adding a separate `<span>` element around each element whose parent isn't completely contained within the selection. (Or you could do it simply by wrapping each non-whitespace Text node between the endpoints.)
bobince
I have gone some way to implementing a feature in Rangy (see my answer) that will apply formatting to a selection by surrounding each text node within the selection with a span, also removing and merging adjacent identical spans where appropriate. I'm hoping to release that within a few weeks.
Tim Down
@bobince: Precisely, its not impossible. That is what wrapSelection() does. Only is doesn't work in IE8.
Dale
+1  A: 

For the jQuery plugin option there's jCaret, you can check out the homepage here and the examples here.

I've used this on a few projects for various applications, works well at removing the cross-browser inconsistencies.

Nick Craver
Looks great, however it only works in inputs and textareas. I have been working on converting it to work on any element but no dice yet. One of the main features is that I need to be able to wrap spans (and any other element I specify) around a user selection. The wrapSelection code (http://plugins.jquery.com/project/wrapSelection) works perfect and I've modified it for my needs, however, the code for some reason doesn't work in IE8, even though it boasts support for IE.
Dale
+1  A: 

I've recently been working on a cross-browser Range and selection library called Rangy. In its current version it's not dissimilar in concept to IERange but goes beyond it in terms of implementation of the DOM level 2 Range and HTML 5 selection specifications, and also in terms of stability and workarounds for browser bugs. There's currently a pre-alpha release that is stable and (in my opinion) the best there is out there.

There are other features that I intend to add but I've initially focussed on creating a really good cross-browser Range and selection implementation, which is pretty much complete in the current release.

http://code.google.com/p/rangy

Update: Added example

The following uses some Rangy extensions to Ranges to easily iterate over text nodes within a selection and surround each one:

function surroundSelectedText(templateElement){
    var range, sel = rangy.getSelection();
    var ranges = sel.getAllRanges();
    var textNode, it, el;
    for (var i = 0, len = ranges.length; i < len; ++i) {
        range = ranges[i];
        // If one or both of the range boundaries falls in the middle
        // of a text node, the following line splits the text node at the
        // boundary
        range.splitBoundaries();

        // The following line creates a simple iterator that iterates
        // over the nodes within the range. The first parameter is an
        // array of valid nodeTypes (in this case, text nodes only)
        it = range.createNodeIterator([3]);

        while ( (textNode = it.next()) ) {
            el = templateElement.cloneNode(false);
            textNode.parentNode.insertBefore(el, textNode);
            el.appendChild(textNode);
        }
    }
}

var span = document.createElement("span");
span.style.color = "green";
span.style.fontWeight = "bold";

surroundSelectedText(span);
Tim Down
Wonderful! I will take a look.
Dale
Once you have support for wrapping ranges with spans this will be, (in my knowledge) feature complete. Post back when you release that part of the code. Unfortunately I have to have this fixed and completed within a day or so.
Dale
Will post an example a bit later...
Tim Down
Example added now.
Tim Down
@Tim: Your library is genius. Thanks!
Dale