0

I'm using rangy and have a case with a contenteditable div where the users selection can be saved and later restored so that HTML can be inserted.

My problem is that if the user selects within a header element, I don't want the html inserted within a header.

So I'm trying to figure out how to use rangy so that if the the selection is made within a header then I can move it before the header element.

So if the user selects within an h1:

<div id="editable" contenteditable>
     <h1>|user selects here| Header Text</h1>
</div>

Then the saved selection would be moved before the h1:

| selection boundary moved here |<div id="editable" contenteditable>
     <h1>|user selects here| Header Text</h1>
</div>

I've tried the following to see if I could move the selection boundary:

var sel = rangy.getSelection();
var range = sel.getRangeAt(0);

range.setStartBefore(sel.anchorNode.parentNode);

sel.removeAllRanges();
sel.addRange(range);

selected = rangy.saveSelection();

But when I select within the H1, it still sets the saved selection boundaries within the H1 and not before it. I'm not sure how I can get the boundaries moved before the header element.

Frank
  • 163
  • 2
  • 3
  • 11
  • This is likely related to how the browser reports the selection, which varies between browsers, particularly when the selection boundary is at the edge of an element or text node. – Tim Down Sep 13 '12 at 08:36

1 Answers1

0

I couldn't figure out how to do this with rangy and finally ended up handling the clean up afterwards with jQuery. Not sure if it's the best way, but it's working for me. Basically, I wanted to remove any divs that might get placed within a header:

$('#cleanup').click(function(e){

        e.preventDefault();

        var header, clone;

        // loop through each header element
        $(#editor :header').each(function(){

            // assign header element to variable
            header = $(this);

            // go through the header's children
            $(header).children().each(function(){

                // if we have a div in the header,
                if( $(this).is("div")){ 

                    // clone it
                    clone = $(this).clone();

                    // put clone before the header
                    $(header).before(clone);

                    // remove the original from the header
                    $(this).remove();

                }

            });

        });

});
Frank
  • 163
  • 2
  • 3
  • 11