Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In a contenteditable element, move the cursor between HTML tags

http://jsfiddle.net/Y7tgx/2/

Firefox handles this better than Chrome does, but neither exactly the way I want. They both lump all adjacent HTML tags together and treat them as one (which I don't want).

Firefox: when the cursor is left of a tag (or group of adjacent tags) and you press right, the cursor jumps past the first character preceding the tag. Then, if you press left, it goes between the character and the tag. (Same for pressing left then right.)

Chrome: the tag and the first character following it are lumped together. It is impossible to place the cursor between a tag and the following character.

Desired: a tag is treated as a single character with respect to the cursor. If the cursor is to the left of a tag and you press right, it should go to the right of the tag, and vice versa for pressing left.

How can the desired behavior be enforced on the browser?

This is not intended for a WYSIWIG editor. To serve a specific purpose, tags are represented visually in production just as they are in the jsfiddle. Users desire arbitrary control over which element contains the cursor.

b:before, b:after,
i:before, i:after,
p:before, p:after {
    color: blue;
}

b:before {
    content: '<b>';
}

b:after {
    content: '</b>';
}

p:before {
    content: '<p>';
}

p:after {
    content: '</p>';
}

i:before {
    content: '<i>';
}

i:after {
    content: '</i>';
}​

----------

<p contenteditable='true'>regular regular<b>bold</b>regular - 
try moving the cursor to either side of either blue tag.</p>
<p contenteditable='true'>try it in this: regular<b><i>bolditalic</i></b></p>
like image 597
Jordan Avatar asked Nov 13 '22 21:11

Jordan


1 Answers

Modifying the code to make sure that characters aren't skipped would be a reasonable fix, but being able to navigate between adjacent tags or editing tags would be opposed to how browsers treat markup (treating invisible tags as text content). The visual representation of tags should be done as text content in order to do that, and any more magical solution will most likely have to lean on that at some point (so it would be clearer to do it outright). A fairly straightforward approach would be to use something like <span class="tag">&lt;b&gt;</span> and then add JavaScript that attaches to *[contenteditable='true'] span.tag to control the cursor moving over that span as a single unit.

The conversion to/from would likely be best done using server side code, but otherwise using basic introspection in JavaScript would allow for the needed replacement or supplementing of code (replacement would make editing far easier, but simply adding the additional spans would be less invasive if the element structure is fixed and only the text content is being edited.

like image 185
Matt Whipple Avatar answered Nov 15 '22 12:11

Matt Whipple