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());
});