EzDevInfo.com

rangy

A cross-browser JavaScript range and selection library.

Move keyboard caret to the end of element with Rangy

I have several a elements within a contenteditable div. How can I place the keyboard caret at the end of a specific element identified by id and later move it to the end of the div using Rangy?

Thanks in advance and any help appreciated.


Source: (StackOverflow)

Rangy - Module 'WrappedSelection' Not Supported

I am trying to use Rangy in my Google Chrome extension, but I keep on receiving the error "Module 'WrappedSelection' not supported". This is a bare-bones extension so I have not implemented any code in this project other then Rangy.

Does anyone know if Rangy is compatible with a Google Chrome extension?


Source: (StackOverflow)

Advertisements

Rangy (JS/jQuery) split node

How would I split a node/element at a position (selection).

Example I have this markup:

<p>This is <a rel='nofollow' href="">a te|st</a>, you like?</p>

(this pipe represents the position/selection)

I want to convert it to:

<p>This is <a rel='nofollow' href="">a te</a></p>|<p><a rel='nofollow' href="">st</a>, you like?</p>

Maintaining the selection.

Any ideas?

I and using the Rangy library, and also jQuery, but can use raw JS if applicable.


Source: (StackOverflow)

Insert Table into content editable div

I have a fiddle showing what my code is doing. Using javascript/jquery I am trying to insert a table into a content editable div at the current caret position. I am using Tim Down's Rangy library to accomplish this. I am doing this with the following javascript.

var range = getFirstRange();
var el = document.createElement("table");
var tableHtml = "";
for (var a = 0; a <= tableY; a++) {
    if(a%2==0){
       tableHtml += '<tr class="zebra">';
    }
    else{
       tableHtml += '<tr>';
    }
    for (var b = 0; b <= tableX; b++) {
       tableHtml += '<td>&nbsp;</td>';
    }
    tableHtml += '</tr>';   
}
$(el).html(tableHtml); 
range.insertNode(el);
rangy.getSelection().setSingleRange(range);

Just in case it helps here is the getFirstRange function.

function getFirstRange() {
   var sel = rangy.getSelection();
   return sel.rangeCount ? sel.getRangeAt(0) : null;
} 

I need to make valid html wherever this table is placed. for example if the caret is in the middle of a link I am trying to avoid the following html.

<p>some text <a rel='nofollow' href="#">text 
                         <table>
                             <tr>
                               <td>table content</td>
                             </tr>
                         </table> 
              text</a> more text</p> 

I would like it to look like this instead.

<p>some text <a rel='nofollow' href="#">text</a></p>
<table>
   <tr>
     <td>table content</td>
   </tr>
</table>
<p><a rel='nofollow' href="#">text</a> more text</p>

Source: (StackOverflow)

How do I create a range object when I know just the character offsets?

So I have a div that contains a block of text, previously the user has selected some text in this block and I created a range object from this selection. I stored the offset of the selected text's starting and ending points but I am having problems re-creating the range (so i can manipulate it). "quotables" is the div that holds all the text. I dont know what I am doing wrong.



    var theRange = rangy.createRange();
    var node = $('.quotables').html();
    theRange.setStart(node, 14);
    theRange.setEnd(node, 318);


but I keep getting errors: Uncaught Error: NOT_FOUND_ERR: DOM Exception 8
m.setStart
(anonymous function)
d.extend._Deferred.f.resolveWith
d.d.extend.ready
d.c.addEventListener.y


Source: (StackOverflow)

How to get the HTML before, inside, and after a selection (not in textarea)?

Here is what I am trying to accomplish: When a user uses a mouse, keyboard, or touch to select text inside "myDiv" I want to acquire three discreet chunks of HTML: the HTML before the selection (to the "left" of it), the HTML inside the selection, and the HTML after the selection (to the "right" of it). The html should be as it would appear with myDiv.innerHTML.

The selection might start or end inside a tag pair (i.e., the isolated selection isn't necessarily valid HTML). I don't need to deal with special scenarios like absolute-positioned elements within the selection; all of the selections I am concerned with will be constrained to one div that will contain basic tags like strong, em, ul, ol, h1, image, and table.

The closest I've come is using rangy to snag the selection and calling selection.getRangeAt(0).cloneContents() to get the selection HTML. This works well enough until I make a selection that is invalid in isolation, and the browser alters the HTML of the document fragment to make it valid markup.

Extra Information: Here's why I need this:

I am creating a document feedback system, so I need to save the selection information to a database for later retrieval and reconstitution. Normally I would save the selection using the DOM path and the selected text, but the text may change between saving and reconstitution. For example, the author might move entire paragraphs around, delete sections, etc. The DOM path becomes pretty useless then.

So my (imperfect) plan is to store the selection as [offset, length, html_snippet]. That's the "position". I'll also store the html snippets that came directly before and after the selected text. This is the "context".

Using a combination of these data I should be able to relocate the originally selected text most of the time, even if it has moved or partially changed. When that fails, the UI will have a way to address it, but I'd like that to occur as infrequently as possible.

Superthanks!


Source: (StackOverflow)

contenteditable div: IE8 not happy with backspace remove of HTML element

I am making use of a contenteditable div in combination with the rangy Javascript library to insert HTML at the cursor position.

End of the day the contents of the div commonly looks like:

<div contenteditable="true">
    "Hello "
    <button contenteditable="false" data-id="147">@John Smith</button>
    " "
</div>

Users get suggested upon pressing '@' and get subsequently inserted as a button when selected (ala Google Plus). I also insert a &nbsp; after this button.

The button gets removed in Chrome/Safari/Firefox when you hit backspace (after first removing the &nbsp;), but not in IE8. In IE8 the cursor merely jumps over the button without removing it. What's even more bizarre in IE8 is if you leave the &nbsp; next to the button - and rather place the cursor right next to the button - it removes the button on backspace. So it's happy when there's a &nbsp; to the right of the cursor.

Does anyone know what I need in order to make IE8 work i.t.o. removing the button upon backspace without the need for a &nbsp; to the right of the cursor? (some info on this strange behaviour might also help)

P.S. I haven't tested other versions of IE


Source: (StackOverflow)

replace innerHTML in contenteditable div

i need to implement highlight for numbers( in future im add more complex rules ) in the contenteditable div. The problem is When im insert new content with javascript replace, DOM changes and contenteditable div lost focus. What i need is keep focus on div with caret on the current position, so users can just type without any issues and my function simple highlighting numbers. Googling around i decide that Rangy library is the best solution. I have following code:

function formatText() {

              var savedSel = rangy.saveSelection();
              el = document.getElementById('pad');
              el.innerHTML = el.innerHTML.replace(/(<([^>]+)>)/ig,"");
              el.innerHTML = el.innerHTML.replace(/([0-9])/ig,"<font color='red'>$1</font>");
              rangy.restoreSelection(savedSel);
          }

<div contenteditable="true" id="pad" onkeyup="formatText();"></div>

The problem is after function end work focus is coming back to the div, but caret always point at the div begin and i can type anywhere, execept div begin. Also console.log types following Rangy warning: Module SaveRestore: Marker element has been removed. Cannot restore selection. Please help me to implement this functional. Im open for another solutiona, not only rangy library. Thanks!

http://jsfiddle.net/2rTA5/ This is jsfiddle, but it dont work properly(nothing happens when i typed numbers into my div), dunno maybe it me (first time post code via jsfiddle) or resource doesnt support contenteditable. UPD* Im read similar problems on stackoverflow, but solutions doesnt suit to my case :(


Source: (StackOverflow)

Remove all HTML tags inside of selection in contenteditable

I have a <div /> which is contenteditable and can contain several types of HTML elements such as <span />, <a />, <b />, <u /> and so on.

Now when I select text in my contenteditable I would like to have a button that removes all the styles within the selection.

Example 1:

The Selection:

Hello <b>there</b>. I am <u>a selection</u>

would become:

Hello there. I am a selection

Example 2:

The Selection:

<a rel='nofollow' href="#">I am a link</a>

would become:

I am a link

You get the idea...

I have found this helpful function http://stackoverflow.com/a/3997896/1503476 which replaces the current selection with custom text. But I just cannot get the content of the selection first and strip the tags out before replacing it. How can I do that?


Source: (StackOverflow)

Could not complete the operation due to error 800a025e

What does this error mean in IE10/11:

Error: Could not complete the operation due to error 800a025e. 

And how would I debug it?

It says its this line:

this.nativeSelection.removeAllRanges();

https://code.google.com/p/rangy/source/browse/trunk/src/js/core/wrappedselection.js#416

See it in action here: http://panmedia.github.io/raptor-editor/tests/cases/selection/selection-expand.html


Source: (StackOverflow)

jQuery doesn't support .has in IE8? what is a work around?

code: http://jsfiddle.net/4hV6c/4/ just make any selection, and you'll get a script error in ie8

I'm trying to do this:

$(end_node.parentNode).has(start_node)

which in modern browsers (chrome, ff, opera, etc) returns [] if start_node is not in end_node.parentNode, and returns the element (I forget which) if it is found.

now, end_node is a text element, and the parentNode is an actual DOM entity. IE will perform .has on just $(end_node).has(start_node) but that is obviously different behavior.

Is there a work around to get this to work?

  • in IE the fiddle will error, other browsers will alert you with a boolean value.

UPDATE: here is a word around that overrides .has() for my specific scenario.. not sure if it works for all the cases of .has, as I don't know them all. http://jsfiddle.net/8F57r/13/


Source: (StackOverflow)

Converting rich-text to plain-text when pasting in contenteditable div [duplicate]

This question already has an answer here:

Im trying to create a contenteditable div with the behaviour of chrome's 'plaintext-only'. So, users can only input plain-text and when copying rich-text it is pasted as plain-text. In my script @-mentions are converted to buttons and added using Rangy.js

In normal contenteditable div's rich-text can be pasted in and I need to convert that to normal text. The only problem is is detecting what is pasted, then convert it to text and insert it at the right position and after restore the carrot position. It is even harder when more text is selected over more lines.

Do I think to hard and is there a more simple solution? Or anyone can suggest the most light weight editor?

thanks!


Source: (StackOverflow)

Getting the parent node for selected text with rangy library

I'm using the rangy library and can select text in a content editable as follows:

var sel = rangy.getSelection();
alert(sel);

I can't figure out how to get the selected text parent node/element. For example, if I'm selecting text that is

<strong>My Text</strong> 
or
<h1>My Title</h1>

how can I include the strong node or H1 element also?


Source: (StackOverflow)

Rangy & ContentEditable - Set the Caret

I'm trying out the latest version of the "rangy" jQuery plugin (1.2 beta) to set the caret in a contenteditable DIV with a specific offset.

However, it responds with a weird error in Firefox: Security error" code: "1000

Here is the offending code:

var el = $("#editablediv"), index = 11;
var range = rangy.createRange();
range.setStart(el, index);
var sel = rangy.getSelection();
sel.setSingleRange(range);

The code fails when calling the setStart function.

Could anyone give an example of the proper usage of rangy please?


Source: (StackOverflow)

Set anchor name with execCommand

I know how to set an <a /> tag with the href attribute in a contenteditable like this:

execCommand("CreateLink", false, "#jumpmark");

which will result in

<a rel='nofollow' href="#jumpmark">selection</a>

However I cannot figure out how to set an anchor name instead of the href.
This is my desired result:

<a name="jumpmark">selection</a>

Can anyone help me?

Side notes: I am using jQuery and Rangy as libraries, however I would prefer a solution that works directly with execCommand.

Update: Here's a jsfiddle: http://jsfiddle.net/fjYHr/ Select some text and click the button. All I want is that with the button click a link is inserted with a name attribute set instead of the href.


Source: (StackOverflow)