(e-mail address removed) wrote:
Hi,
I am using it to store what a users selects or highlights within a html
page. That position plus the length of the highlight will then be
passed to an application to be stored so that when they revisit the
page, what the user selected will still be highlighted. The app needs
the postion on the page, as well as the length of the highlight.
I'm starting to see what you want, however I'm afraid you won't be be
able to do it the way you want, given the way the page is parsed
client-side: basically you manipulate nodes, not text.
What I can suggest is the following: capture the user selection, alter
the tree, store the altered tree in a DB with the username, and send
the altered tree back when requested by the user. The code below should
work in IE/Mozilla (slightly tested only, I'm on my way to holidays).
Given the nature fo the text to be highlighted, then you might consider
sending only a part of the tree, or even adopt a text-based highlight
(is there's no more than 1 occurrence of the text in your page - you
still don't tell the "real" why
).
---
<script type="text/javascript">
var SelectionManager = (function() {
var MARKER_CLASS="markerClass";
function getSel(){
var sel=null;
if(
typeof document.selection!="undefined" &&
document.selection &&
document.selection.type=="Text"
){
sel=document.selection;
} else if(
window.getSelection &&
window.getSelection().rangeCount>0
){
sel=window.getSelection();
}
return sel;
}
function createRange(){
var rng=null;
if(document.body && document.body.createTextRange) {
rng=document.body.createTextRange();
} else if(document.createRange) {
rng=document.createRange();
}
return rng;
}
function moveRange(rng, el){
var moved=false;
if(rng.moveToElementText){
rng.moveToElementText(el);
moved=true;
} else if(rng.selectNodeContents) {
rng.selectNodeContents(el);
moved=true;
}
return moved;
}
function selectRange(rng){
if(rng.select){
rng.select();
} else if(window.getSelection) {
var sel=window.getSelection();
if(sel && sel.removeAllRanges && sel.addRange) {
sel.removeAllRanges();
sel.addRange(rng);
}
}
}
function createRangeFromSel(sel){
var rng=null;
if(sel.createRange) {
rng=sel.createRange();
} else if(sel.getRangeAt) {
rng=sel.getRangeAt(0);
if(rng.toString()=="") rng=null;
}
return rng;
}
function markRange(rng){
var marked=false;
if(rng.pasteHTML){
rng.pasteHTML(
"<span class='"+MARKER_CLASS+"'>"+rng.text+"<\/span>"
);
marked=true;
} else if(rng.extractContents){
var span=document.createElement("span");
span.className=MARKER_CLASS;
span.appendChild(rng.extractContents());
rng.insertNode(span);
marked=true;
}
return marked;
}
function createSelectionFromNode(node){
var rng=createRange();
if(rng){
if(moveRange(rng, node)){
selectRange(rng);
}
}
}
document.onmouseup = function(evt){
var sel=getSel(), rng;
if(sel) {
rng=createRangeFromSel(sel);
if(rng) {
SelectionManager.lastSelection=rng;
}
}
}
return {
lastSelection : null,
markLastSelection : function() {
return this.lastSelection && markRange(this.lastSelection);
},
highlightSelection : function() {
if(document.getElementsByTagName){
var span=document.getElementsByTagName("span");
for(var ii=span.length; ii--
{
if(span[ii].className.indexOf(MARKER_CLASS)!=-1) {
createSelectionFromNode(span[ii]);
break;
}
}
}
}
};
})();
function submitHandler(frm){
frm.elements['SelectionInfo'].value=
SelectionManager.markLastSelection()?document.body.innerHTML:"";
return true;
}
window.onload = function(evt){
SelectionManager.highlightSelection();
}
</script>
<div>Hello, World!</div>
<form action="foo" onsubmit="return submitHandler(this)">
<input type="hidden" name="SelectionInfo">
<input type="submit" value="Send selection">
</form>