Reputation: 493
I'm developing a firefox extension. So, when the user selects a text and then right-clicks in order for some context menus to appear, i should be able to retrieve from that selection a list with all the links contained in it. How am i able to do that? i see that currentDocument.getSelection() only retrieves simple text not the whole HTML data.
Thank you TIM . I have one more problem though! This is how i use your function . Where i call it the text is bolded.
The problem is that when i select a text and right the text that activates your function, if the cursor is over normal text i get the links allright; if the cursor is over LINK TEXT (the actual link) i get and undefined response. Why might this happen?
window.addEventListener("contextmenu", function(e) {
getSelectionLink();
}, false);
function getSelectionLink() {
var SelectionText = "";
var trywindow = false;
var start = 0;
var stop = 0;
var focusedElement = document.commandDispatcher.focusedElement;
if(focusedElement && null != focusedElement)
{
try
{
alert(focusedElement.value);
}
catch(e)
{
trywindow = true;
}
}
else
{
trywindow = true;
}
if(trywindow)
{
var focusedWindow = document.commandDispatcher.focusedWindow;
var winWrapper = new XPCNativeWrapper(focusedWindow, 'document');
var Selection = winWrapper.getSelection();
alert(getSelectedElements(winWrapper, "a"));
//parseSelection(Selection);
}
}
Upvotes: 2
Views: 2560
Reputation: 324507
Here's a function that will get you a list of all elements with a particular tag name that are wholly or partially selected. It works in all major browsers except IE < 9:
function getSelectedElements(win, tagName) {
var sel = win.getSelection(), selectedElements = [];
var range, elementRange, elements;
if (sel.getRangeAt && sel.rangeCount) {
elementRange = win.document.createRange();
for (var r = 0; r < sel.rangeCount; ++r) {
range = sel.getRangeAt(r);
containerEl = range.commonAncestorContainer;
if (containerEl.nodeType != 1) {
containerEl = containerEl.parentNode;
}
if (containerEl.nodeName.toLowerCase() == tagName) {
selectedElements.push(containerEl);
} else {
elements = containerEl.getElementsByTagName(tagName);
for (var i = 0; i < elements.length; ++i) {
elementRange.selectNodeContents(elements[i]);
if (elementRange.compareBoundaryPoints(range.END_TO_START, range) < 1
&& elementRange.compareBoundaryPoints(range.START_TO_END, range) > -1) {
selectedElements.push(elements[i]);
}
}
}
}
elementRange.detach();
}
return selectedElements;
}
console.log( getSelectedElements(currentWindow, "a") );
Upvotes: 3
Reputation: 57651
You should be using currentWindow.getSelection()
, it returns a Selection
object (see https://developer.mozilla.org/en/DOM/Selection). Given that only one part of a node might be selected it isn't quite clear what kind of HTML data you expect. Here is an approach that will give you too much in this scenario (much like "View Selection Source" feature does):
var selection = currentWindow.getSelection();
var range = selection.getRangeAt(0);
var container = range.commonAncestorContainer;
if (container instanceof Element)
alert(container.innerHTML); // Container element
else
alert(container.nodeValue); // A single text node
Upvotes: 0