473,327 Members | 1,892 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,327 software developers and data experts.

Getting highlighted text + position in document

JE
Hi!
I am snooping around all sorts of websites and faqs, in search of a way to
pick up any selected (mouse-highlighted) text in a HTML page, and store it
in a JavaScript variable.

I have found an excellent site which actually has a great cross-platform
script for doing just this;

http://www.quirksmode.org/js/selected.html

My problem is that I also need the position of the selected text within
the document. I am finishing a Perl program for editing HTML content, and
I'd like to use such a script to submit words/paragraphs back to the
program, requesting HTML formatting tags. E.g. user selects "very
important", clicks the BOLD button. Then JS gets the text and its
position which is submitted to the Perl program, which adds <B></B> tags,
and refreshes the document.

Without the positions, I naturally get all occurrences of "very important"
in the document in boldface...

Please have a look at the two-liner script snippet in the Quirksmode
document. Is there any way to access position info without losing
cross-platform stability?
Your help would be greatly appreciated! I would love to see this idea
work.

Sincerely,

Joakim Knudsen
jo*****@ii.uib.no
Norway

--
jo************@nospam.spray.no

Remove nospam to reply!
Jul 23 '05 #1
4 8536
JE wrote:
My problem is that I also need the position of the selected text within
the document. I am finishing a Perl program for editing HTML content, and
I'd like to use such a script to submit words/paragraphs back to the
program, requesting HTML formatting tags. E.g. user selects "very
important", clicks the BOLD button. Then JS gets the text and its
position which is submitted to the Perl program, which adds <B></B> tags,
and refreshes the document.


This is not a simple problem; the position you're looking for in your
Perl program is a text-based one. However, you only have access to a
serialized source on the client, which means that the position defined
in regards of text isn't really an interesting one, and can vary across
user agents.

If it is acceptable to you to have the "bold" part be done client side
(and it should be since you rely on client objects to start the whole
process), then you could go for a client-side solution, using ranges -
submitting the serialized source to the Perl program afterwards, if
history is needed.

Ranges' models differ between IE and W3C models; IE's model is
text-oriented, offering a great deal of useful methods to directly
manipulate the text, while the W3C's one is more node-oriented, thus
requiring more code to achieve similar results (reorganizing, splitting
nodes etc).
---

<pre style="text-align:center">
Trois allumettes une à une allumées dans la nuit
La première pour voir ton visage tout entier
La seconde pour voir tes yeux
La dernière pour voir ta bouche
Et l'obscurité tout entière pour me rappeler tout cela
En te serrant dans mes bras
</pre>

<input type="button" value="Make Bold" onclick="makeBold()">

<script type="text/javascript">
var makeBold = function() {

function getSel() {
if(window.getSelection) return window.getSelection();
else if(typeof document.selection!="undefined")
return document.selection;
}

function getSelectionRange() {
var sel=getSel();
if(sel) {
if(sel.getRangeAt && sel.rangeCount) return sel.getRangeAt(0);
else if(sel.createRange) return sel.createRange();
}
}

function emptySelection(){
var sel=getSel();
if(sel) {
if(sel.empty) sel.empty();
else if(sel.removeAllRanges) sel.removeAllRanges();
}
}

function _makeBold(){
var rng=getSelectionRange();

if(rng) {
if(rng.execCommand) {
rng.execCommand("bold");
} else if(rng.extractContents){
var endc=rng.endContainer;
var action=1; // make bold
var b, src=rng.extractContents();

do {
if(endc.nodeName.toLowerCase()=="b") {
action=0; // unbold
break;
}
} while((endc=endc.parentNode));

if(action==1){
b=document.createElement("b");
b.appendChild(src);
rng.insertNode(b);
} else {
rng.insertNode(
function(nodeList, parent){
parent=parent||document.createDocumentFragment();
for(var ii=0;ii<nodeList.length;ii++)
parent.appendChild(
arguments.callee(
nodeList[ii].childNodes,
nodeList[ii].nodeName.toLowerCase()=="b" ?
null : nodeList[ii--]
)
);
return parent;
}(src.childNodes)
);
}
emptySelection();
}
}
return true;
}

function doNothing() {
return false;
}

return typeof getSel()!="undefined" ? _makeBold : doNothing;
}();
</script>

---
HTH
Yep.
Jul 23 '05 #2
JE
Hi!

I looked at your solution, and it worked!
Still, I have trouble understanding your code, with all the DOM tree
manipulations. Plus I need to save the changes in style in a database, so
I would like to do the change at server-side; i.e. inserting <b></b>
tags...
- Joakim

In article <41***********************@news.free.fr>, y-*******@em-lyon.com
wrote:
JE wrote:
My problem is that I also need the position of the selected text within
the document. I am finishing a Perl program for editing HTML content, and
I'd like to use such a script to submit words/paragraphs back to the
program, requesting HTML formatting tags. E.g. user selects "very
important", clicks the BOLD button. Then JS gets the text and its
position which is submitted to the Perl program, which adds <B></B> tags,
and refreshes the document.


This is not a simple problem; the position you're looking for in your
Perl program is a text-based one. However, you only have access to a
serialized source on the client, which means that the position defined
in regards of text isn't really an interesting one, and can vary across
user agents.

If it is acceptable to you to have the "bold" part be done client side
(and it should be since you rely on client objects to start the whole
process), then you could go for a client-side solution, using ranges -
submitting the serialized source to the Perl program afterwards, if
history is needed.

Ranges' models differ between IE and W3C models; IE's model is
text-oriented, offering a great deal of useful methods to directly
manipulate the text, while the W3C's one is more node-oriented, thus
requiring more code to achieve similar results (reorganizing, splitting
nodes etc).
---

<pre style="text-align:center">
Trois allumettes une à une allumées dans la nuit
La première pour voir ton visage tout entier
La seconde pour voir tes yeux
La dernière pour voir ta bouche
Et l'obscurité tout entière pour me rappeler tout cela
En te serrant dans mes bras
</pre>

<input type="button" value="Make Bold" onclick="makeBold()">

<script type="text/javascript">
var makeBold = function() {

function getSel() {
if(window.getSelection) return window.getSelection();
else if(typeof document.selection!="undefined")
return document.selection;
}

function getSelectionRange() {
var sel=getSel();
if(sel) {
if(sel.getRangeAt && sel.rangeCount) return sel.getRangeAt(0);
else if(sel.createRange) return sel.createRange();
}
}

function emptySelection(){
var sel=getSel();
if(sel) {
if(sel.empty) sel.empty();
else if(sel.removeAllRanges) sel.removeAllRanges();
}
}

function _makeBold(){
var rng=getSelectionRange();

if(rng) {
if(rng.execCommand) {
rng.execCommand("bold");
} else if(rng.extractContents){
var endc=rng.endContainer;
var action=1; // make bold
var b, src=rng.extractContents();

do {
if(endc.nodeName.toLowerCase()=="b") {
action=0; // unbold
break;
}
} while((endc=endc.parentNode));

if(action==1){
b=document.createElement("b");
b.appendChild(src);
rng.insertNode(b);
} else {
rng.insertNode(
function(nodeList, parent){
parent=parent||document.createDocumentFragment();
for(var ii=0;ii<nodeList.length;ii++)
parent.appendChild(
arguments.callee(
nodeList[ii].childNodes,
nodeList[ii].nodeName.toLowerCase()=="b" ?
null : nodeList[ii--]
)
);
return parent;
}(src.childNodes)
);
}
emptySelection();
}
}
return true;
}

function doNothing() {
return false;
}

return typeof getSel()!="undefined" ? _makeBold : doNothing;
}();
</script>

---
HTH
Yep.


--
jo************@nospam.spray.no

Remove nospam to reply!
Jul 23 '05 #3
On Sun, 25 Jul 2004 23:38:41 +0200, JE wrote:
Plus I need to .... i.e. inserting <b></b>
tags...


Why don't you try some *deleting* as well JE?
<http://www.physci.org/kbd.jsp?key=del>

That last post of yours came to 145 lines, 124
of which did not need to be requoted..

--
Andrew Thompson
http://www.PhySci.org/ Open-source software suite
http://www.PhySci.org/codes/ Web & IT Help
http://www.1point1C.org/ Science & Technology
Jul 23 '05 #4
JE wrote:
Plus I need to save the changes in style in a database, so
I would like to do the change at server-side; i.e. inserting <b></b>
tags...


I can understand the feeling, however doing the change server-side would
be highly difficult, since the position has some sense on the client
only, in the DOM. You could of course do some text analysis on a
serialized DOM (say, obtained by innerHTML) also taking into account
nesting issues, or transmit a node/offset object then rebuild the
position server-side using a DOM parser, but as you can see this would
be a real pain to implement.

Actually, you don't need to do the change server-side to keep the
history; once the user has highlighted the text as required, he just has
to submit a form which will retrieve the source client-side (be it the
serialized source from innerHTML or, maybe better, a manually built
source from the DOM tree) and post it to the server.
Slightly tested only:

---
<pre id="text">
<b>He<i>ll</i>o</b>, World!
</pre>

<form action="foo" method="post" onsubmit="return saveChanges(this)">
<input type="hidden" name="textModified" value="">
<input type="submit" value="Save changes">
</form>

<script type="text/javascript">
function saveChanges(frm){
if(document.getElementById &&
document.body &&
document.body.childNodes &&
typeof document.body.nodeValue!="undefined") {

var root=document.getElementById("text");
var txt=[];
var getHTML = function(node) {
var buf=[];
if(node.nodeType==1){
buf.push("<"+node.nodeName+">");
for(var ii=0; ii<node.childNodes.length; ii++)
buf.push(arguments.callee(node.childNodes[ii]));
buf.push("<\/"+node.nodeName+">");
} else if(node.nodeType==3){
buf.push(node.nodeValue);
}
return buf.join("");
}

//frm.elements["textModified"].value=root.innerHTML;
for(var j=0; j<root.childNodes.length; j++)
txt.push(getHTML(root.childNodes[j]));
frm.elements["textModified"].value=txt.join("");
return true;
}
return false;
}
</script>
---
Jul 23 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

21
by: Michael Bierman | last post by:
Please forgive the simplicy of this question. I have the following code which attempts to determine the color of some text and set other text to match that color. It works fine in Firefox, but does...
2
by: Julian Jordan | last post by:
Hi I'm trying to write a system in which you can highlight some text in a form box, click a button (or press a key combination) and the text highlighted gets surrounded by a given html tag. ...
14
by: Gary Shell | last post by:
I have five comboboxes each has a item listed populated by hand in the IDE. Each has the text property bound to a text field in the database. When I initially fill the dataset and display the page...
4
windows_mss
by: windows_mss | last post by:
When I Select Source & Destination Dynamically, Path Getting Scatter Across The Map... hi, i can able to get the Correct Route and Path for the corresponding Source and destination, like...
12
by: tim | last post by:
I am using foldoutmenu 3 and am having problems with viewing my menus in firefox. On my sub3 menus i have more than one line of text in some places. firefox does not recognise that there is more...
7
by: raylaur | last post by:
I'm using a javascript "slide" function to move a <div> layer in 10 pixel increments from one location on a page to another. The layer contains a GIF image. It's basically a side panel that flies out...
1
by: ced69 | last post by:
having trouble getting marquee to work get object required errors tring t <title>This Month at the Chamberlain Civic Center</title> <link href="styles.css" rel="stylesheet"...
4
by: N00b13 | last post by:
I have a great JS menu but I have to update every page each time I want to change a link. Is there a way to store my links in a file and call it so i only change that file? (what I have tried so far...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.