Window.Getselection() Gives Me the Selected Text, But I Want the HTML

Retrieve html code of selected text

Do you have a mouse event listener or something before you do contentWindow.getSelection?

If you do you can get the selected node by doing:

    function onMouseUp(event) {
var aWindow = event.target.ownerDocument.defaultView;
// should test if aWindow is chrome area or actually content area
var contentWindow = aWindow.document instanceof Ci.nsIHTMLDocument ? aWindow : null; // i guessed here but testing if its content window is done in some similar way
if (!contentWindow) { return }
// do contentWindow.getSelection im not familiar with the code, if selection exists // check if more then one range selected then get node for each, however im going to assume only one range is selected
var nodeOfFirstRange = event.explicitOriginalTarget
var elementOfNode = nodeOfFirstRange.parentNode;
var htmlOfElement = elementOfNode.innerHTML;
}

Services.wm.getMostRecentWindow('navigator:browser').gBrowser.addEventListener('mouseup');

issue with this code is if user mouses down in content window and then highlights and mouseup while mouse its outside of content window, like on chrome window or even outside the browser (like if the browser window was not in maximum or if user mousedup in taskbar of os etc) so just use this code as a guide

How to get selected text with JavaScript

One problem that you may well be experiencing is that in some browsers (notably IE), by the time the button's click event fires, the selection has been destroyed. You can fix this by using the mousedown event instead (which still allows the selection to be destroyed, but only after the event has been handled), or by making the button unselectable.

I assume your button is not an actual button input, because this behaviour only happens for regular elements.

Demo: http://jsfiddle.net/L9bvU/1/

function GetSelectedText () {    if (window.getSelection) {  // all browsers, except IE before version 9        var range = window.getSelection ();        alert (range.toString ());    }     else {        if (document.selection.createRange) { // Internet Explorer            var range = document.selection.createRange ();            alert (range.text);        }    }}
span {    background-color: #ccc;    padding: 3px;    border: solid gray 1px;    }
*[unselectable="on"] { -moz-user-select: -moz-none; -khtml-user-select: none; -webkit-user-select: none;
/* Introduced in IE 10. See http://ie.microsoft.com/testdrive/HTML5/msUserSelect/ */ -ms-user-select: none; user-select: none;}
<div contenteditable="true">Please select some of this text and press a button below</div>
<span onclick="GetSelectedText()">Click</span><span onmousedown="GetSelectedText()">Mousedown</span><span unselectable="on" onclick="GetSelectedText()">Click, unselectable</span>

window.getSelection() doesn't give html nodes

The window.getSelection() returns a selection object (ref) that includes the start (anchorNode) and end (extentNode). So based on the HTML you provided - with the ID's modified to not using only numbers (ref) - here is a demo. Click on any word, or select a group of words to see them get the "red" class name.

Modified HTML

<div>
<p><span id="s1">word1</span> <span id="s2">word2</span> </p>
<div><span id="s3">word3</span> <span id="s4">word4</span></div>
<ul>
<li><span id="s5">word5</span> <span id="s6">word6</span></li>
</ul>
<p><span id="s7">word7</span> <span id="s8">word8</span> <strong><span id="s9">word9</span></strong> </p>
</div>

Script

$('div').bind('mouseup', function(){

var i,
s = window.getSelection(),
// get ID of starting node
start = parseInt((s.anchorNode.parentNode.id || '').substring(1), 10),
// get ID of end node
end = parseInt((s.extentNode.parentNode.id || '').substring(1), 10),
// start gathering spans
spans = $('#s' + start);

// remove selected class
$('span[id^=s]').removeClass('red');

// add each span
for (i = start; i <= end; i++) {
spans = spans.add( $('#s' + i) );
}

// add selected class
spans.addClass('red');

});


Can I change the HTML of the selected text?

The jQuery wrapselection plugin sounds like what you're looking for http://archive.plugins.jquery.com/project/wrapSelection . What you're asking for is not directly possible though, the plugin works by adding in extra nodes around the surrounding text which may not be 100% reliable (particularly in IE6-8)

How to Make windows.getSelection Return Selected Text

For anyone else who gets stuck on this:

Be sure to have "active tab" in permissions.

To pull the selected text from the active tab:

function getSelectedText(){    chrome.tabs.executeScript({code: 'getSelection().toString()'},     res => callback(res)  //res => { alert(res[0]) });    );}
var blah;function callback(results){ console.log(results); blah = results[0];}

Get selected text and selected nodes on a page?

You are in for a bumpy ride, but this is quite possible. The main problem is that IE and W3C expose completely different interfaces to selections so if you want cross browser functionality then you basically have to write the whole thing twice. Also, some basic functionality is missing from both interfaces.

Mozilla developer connection has the story on W3C selections. Microsoft have their system documented on MSDN. I recommend starting at PPK's introduction to ranges.

Here are some basic functions that I believe work:

// selection objects will differ between browsers
function getSelection () {
return ( msie )
? document.selection
: ( window.getSelection || document.getSelection )();
}

// range objects will differ between browsers
function getRange () {
return ( msie )
? getSelection().createRange()
: getSelection().getRangeAt( 0 )
}

// abstract getting a parent container from a range
function parentContainer ( range ) {
return ( msie )
? range.parentElement()
: range.commonAncestorContainer;
}

Position changes every time with window.getSelection()

See this update: jsfiddle.

First, on the mousedown, you can unwrap the span as so:

$(document).on("mousedown",".wrap",function(){      
$('.highlight').contents().unwrap();
});

Secondly, the problem with using the range.startOffset and range.endOffset is that you the start is relative to the containing element which could be the highlight span which causes you to replace the incorrect text on subsequent selections. Instead, replace the selection with the span as so:

$(document).on("mouseup",".wrap",function(){
var highlight = window.getSelection();
if(highlight.toString().length>=1){
var range = highlight.getRangeAt(0);
var selectionContents = range.extractContents();
var spn = document.createElement("span");
spn.className='highlight';
spn.appendChild(selectionContents);
range.insertNode(spn);
highlight.removeAllRanges();
}
});

Information from MDN Range.startOffset, specifically:

the startContainer is a Node of type Text, Comment, or CDATASection, then the offset is the number of characters from the start of the startContainer to the boundary point of the Range. For other Node types, the startOffset is the number of child nodes between the start of the startContainer and the boundary point of the Range.

Also, this answer.



Related Topics



Leave a reply



Submit