jQuery Partial Elements (aka Ranges)

http://stackoverflow.com/questions/6264458/can-jquery-work-with-partial-elements-ranges

by Benjamin Lupton

HTML

<div id="content"></div>
<textarea id="result"></textarea>
<a href="http://stackoverflow.com/q/6264458/130638">source</a>

CSS

strong {
    font-weight:bold;
}
em {
    font-style:italic;
}

#result {
    width:100%;
    height:5em;
}

JavaScript

console.clear();

String.prototype.textToHtmlIndex = function(index){
    var parts = this.split(/<|>/g), i, textIndex = 0, htmlIndex = 0;
    for ( i=0; i<parts.length; ++i ) {
        var part = parts[i];
        if ( i ) {
            htmlIndex++;
        }
        
        if ( i % 2 ) {
            // html
            htmlIndex += part.length;
            //console.log('html:',part,[textIndex,htmlIndex,index]);
        }
        else {
            // text
            htmlIndex += part.length;
            textIndex += part.length;
            //console.log('text:',part,[textIndex,htmlIndex,index]);
            if ( textIndex > index ) {
                return htmlIndex - (textIndex-index);
            }
        }
    }
    
    return -1;
};
String.prototype.getDepthIndex = function(index){
    var parts = this.split(/<|>/g), i, depthIndex = 0, htmlIndex = 0;
    for ( i=0; i<parts.length; ++i ) {
        var part = parts[i];
        if ( i ) {
            htmlIndex++;
        }
        
        htmlIndex += part.length;
        
        if ( i % 2 ) {
            // html
            if ( part.length ) {
                if ( part[0] === '/' ) {
                    //console.log('-1', part, [htmlIndex, index]);
                    --depthIndex;
                }
                else {
                    //console.log('+1', part, [htmlIndex, index]);
                    ++depthIndex;
                }
            }
        }
        
        if ( htmlIndex >= index ) {
            return depthIndex;
        }
    }
    
    return depthIndex;
};
String.prototype.textToHtmlIndexes = function(start,finish){
    var startIndex, finishIndex,
        startDepth, finishDepth,
        i,n;
    
    startIndex = this.textToHtmlIndex(start);
    finishIndex = this.textToHtmlIndex(finish);
    
    startDepth = this.getDepthIndex(startIndex);
    finishDepth = this.getDepthIndex(finishIndex);
    
    if ( startDepth > finishDepth ) {
        n =...