Text selection and context menu.

HTML

<script src="http://rangy.googlecode.com/svn/trunk/dev/rangy-core.js"></script>
<script src="http://rangy.googlecode.com/svn/trunk/dev/rangy-cssclassapplier.js"></script>
<div class="container">
    <div class="content text" id="text">
        <div class="inner">
            <h1>HTML Ipsum Presents</h1>
                   
            <p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris <span class="comment" data-id="1">placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum</span> sed, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. <a href="#">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p>
            <p>Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum.</p>
            
            <h2>Header Level 2</h2>
                       
            <ol>
               <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
               <li>Aliquam tincidunt mauris eu risus.</li>
            </ol>
            
            <blockquote><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. <span class="comment" data-id="2">Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero</span> at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est.</p></blockquote>
            
            <h3>Header Level 3</h3>
            
            <ul>
                <li>Lorem ipsum dolor sit amet, <span class="comment" data-id="3">consectetuer...

CSS

/*=BASELINE*/
menu, label, fieldset, div { margin:0; padding:0; }
body {
  font-family:Georgia, Times, "Times New Roman", serif;
  font-size:62.5%;  
}
/*=CONTAINER*/
.container {
    overflow:hidden;
    font-size:1.4em;
    background:#f7f4dd url(http://dev.ljd.dk/resources/text-back-gradient.png) center top no-repeat;
    color:#555;
    position:relative;
    z-index:1;
}
    /*=THEMES*/
    .container.dark {
      background:#000;
      color:#eee;
    }
    .container.light {
      background:#fff;
      color:#333;
    }
/*=TEXT*/
.content {
    padding:2em;
    overflow:hidden;
}
.content .inner {
    width:75%;
    margin:0 auto;
}
.content.show-comments .comment {
    border-bottom:1px dotted #a70000;
    color:#a70000;
    cursor:help;
}
.content.show-comments .comment.highlight {
    background:rgba(200,0,0,0.25);
}
    /*=TYPOGRAPHY*/
    .text {
        line-height:1.5em;
    }
    .text h1, 
    .text h2, 
    .text h3 {
        font-size:2em;
        line-height:1.5em;
        margin-top:0.75em;
    }
    .text h1:first-child, 
    .text h2:first-child, 
    .text h3:first-child {
        margin-top:0;
    } 
    .text h2 {
        font-size:1.5em;
        line-height:1.875em;
    }
    .text h3 {
        font-size:1.285714285714286em;
        line-height:2.035714285714286em;
    }
    .text a {
        color:#0060b2;
    }
    .text strong,
    .text b { 
        font-weight:bold;
    }
    .text em,
    .text i {
        font-style:italic;
    }
    .text ul { 
        list-style:circle;
    }
    .text ol { 
        list-style:decimal;
    }
    .text blockquote {
        padding:0.75em 1.5em;
        font-style:italic;
    }
    .text p {
        margin-bottom:1.5em; 
    }
    .text p:last-child {
        margin-bottom:0; 
    }
/*=TEXT SELECTION PLUGIN*/
.tsns-contextmenu {
    background:#fff;
    border:1px solid #e0e0e0;
    border-radius:4px;
    box-shadow:0 0 3px rgba(255,255,225,0.125);
    overflow:hidden;
}
.tsns-contextmenu a {
   ...

JavaScript

(function($){
    /*
    * Text selection jQuery plugin
    * Utterly dependant on Rangy (http://code.google.com/p/rangy/).
    * @dependency: rangy-core.js
    * @dependency: rangy-cssclassapplier.js
    */
    // Init rangy
    rangy.init();
    // Expose plugin
    $.fn.textSelection = function(options) {
        // Settings
        var settings={
            contextmenu:{
                synthreader:true,
                highlight:true,
                comment:true,
            },
            namespace: 'tsns'
        };
        if(options) $.extend(settings,options);
        
        // Common methods
        var toolkit = {};
        
        // Loop
        return this.each(function() {
            var $t=$(this);
            
            // Setup context menu
            var $contextmenu= $('<div class="'+settings.namespace+'-contextmenu" />').css({'display':'none','position':'absolute'});
            // Synth reader
            if (settings.contextmenu.synthreader) {
                
            }
            // Highlight
            if (settings.contextmenu.highlight) {
                var $highlight = $('<a class="'+settings.namespace+'-highlight" href="#'+settings.namespace+'-highlight">Highlight</a>').appendTo($contextmenu);
            }
            // Comment
            if (settings.contextmenu.comment) {
                
            }
            $contextmenu.appendTo($t);
            
            // Catch selection - event listening 
            var catchSelection = function(e) {
                var tempSelection = rangy.createCssClassApplier(settings.namespace+'-selection-temp', {normalize: true});
                tempSelection.applyToSelection();
            };
            $t.bind({
                mouseup:catchSelection,
                keyup:catchSelection
            });
        });
    }
})(jQuery);

// Execute
$(document).ready(function(){
    console.log($('#text').textSelection());
});