Selecting content in a browser using JavaScript used to be a much more complex problem (I'm pointing a finger firmly at you IE) but modern browsers now seem to provide a fairly uniform interface for the task - although there are still some challenges.

ContentSelect is designed specifically for selecting in-line content within a block level element, it's not (that I'm aware) capable of selecting content beyond this scope reliably. This design decision is due to the approach I took when designing the content editor where individual blocks are made editable rather than the entire page.

Usage

ContentSelect makes selecting page content or querying the current selection straightforward. Let's assume we have the following block of HTML content:

<p id="my-element">The quick brown fox <br />jumps over the <b>lazy dog</b>.</p>

Select

To select content we create a range and then call select() against the block element containing our content:

// Create a new range
var range = new ContentSelect.Range(5, 15);

// Select some content
var element = document.getElementById('my-element');
range.select(element);

Query the current selection

To get a Range representing the currently selected content we call the query() class method against our block element:

// Get the range currently selected
range = ContentSelect.Range.query(element);
console.log(range.get());

>>> [5, 15]

Whitespace

The eagle-eyed amongst you might have noticed that the paragraph I defined for the usage examples doesn't have any white space between the tags and the content. The reason I did this is that white space affects content selection. For example if we defined our content like so:

<p id="my-element">
    The quick brown fox <br />jumps over the <b>lazy dog</b>.
</p>

To select the first word in the paragraph 'The' we need to create a Range for [4, 7] to account for the extra spacing at the start. This is perhaps not what you'd expect, given that positioning the caret at [0, 0] or [4,4] will for all intents and purpose have the same effect for the user.

My advice, where possible, is to work with whitespace trimmed from either inner end of the containing element.

Self-closing tags

FireFox, Chrome and IE all handle caret position for self-closing tags (such as <br>) differently. To introduce some consistency (and sanity) the prepareElement class method is provided. It wraps empty text nodes around each self-closing tag within an element.

I recommend calling prepareElement before selecting or querying the selection of elements:

var element = document.getElementById('my-element');

// Prepare the element for selection/querying
ContentSelect.Range.prepareElement(element);

...safe to call query or select against the element now...

There is a performance penalty for calling prepareElement and so call it only when you need to, ideally initially and then only when the content is changed.

Reference

range = new ContentSelect.Range(from, to)

Create a new Range with a span defined by from and to.

range.isCollapsed()

Return true if the range is collapsed (span of 0).

range.span()

Return the span (distance between the start and end) of the range.

range.collapse()

Collapse th range (right to left).

range.eq(otherRange)

Return true if otherRange is equal to this range.

range.get()

Return the span of the range as an array [start, end].

range.select(element)

Select content within element.

range.set(from, to)

Set the span of the range.

range.prepareElement(element)

Prepare an element for querying and/or selection (see Self-closing tags).

ContentSelect.Range.rect()

Return a bounding rectangle (DOMRect) for the currently selection.

ContentSelect.Range.query(element)

Return a range for the content selected within element.

ContentSelect.Range.unselectAll()

Unselect all selected content on the page.