1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| function getElementsFromSelection(){
var nodes = null, candidates = [], children, el, parent, rng;
rng = getSelectionRange();
selectedText = rng.text;
if (rng) {
parent = getCommonAncestor(rng);
if (parent) {
// adjust from text node to element, if needed
while (parent.nodeType != 1)
parent = parent.parentNode;
// obtain all candidates from parent (excluded)
// up to BODY (included)
if (parent.nodeName.toLowerCase() != "body") {
el = parent;
do {
el = el.parentNode;
candidates[candidates.length] = el;
}
while (el.nodeName.toLowerCase() != "body");
}
// obtain all candidates down to all children
children = parent.all || parent.getElementsByTagName("*");
for (var j = 0; j < children.length; j++)
candidates[candidates.length] = children[j];
// proceed - keep element when range touches it
nodes = [parent];
for (var ii = 0, r2; ii < candidates.length; ii++) {
r2 = createRangeFromElement(candidates[ii]);
if (r2 && rangeContact(rng, r2))
nodes[nodes.length] = candidates[ii];
}
}
}
return nodes;
// Helpers
function getSelectionRange(){
var rng = null;
if (window.getSelection) {
rng = window.getSelection();
if (rng && rng.rangeCount && rng.getRangeAt) {
rng = rng.getRangeAt(0);
}
}
else
if (document.selection && document.selection.type == "Text") {
rng = document.selection.createRange();
}
return rng;
}
function getCommonAncestor(rng){
return rng.parentElement ? rng.parentElement() : rng.commonAncestorContainer;
}
function rangeContact(r1, r2){
var p = null;
if (r1.compareEndPoints) {
p = {
method: "compareEndPoints",
StartToStart: "StartToStart",
StartToEnd: "StartToEnd",
EndToEnd: "EndToEnd",
EndToStart: "EndToStart"
}
}
else
if (r1.compareBoundaryPoints) {
p = {
method: "compareBoundaryPoints",
StartToStart: 0,
StartToEnd: 1,
EndToEnd: 2,
EndToStart: 3
}
}
return p &&
!(r2[p.method](p.StartToStart, r1) == 1 &&
r2[p.method](p.EndToEnd, r1) == 1 &&
r2[p.method](p.StartToEnd, r1) == 1 &&
r2[p.method](p.EndToStart, r1) == 1 ||
r2[p.method](p.StartToStart, r1) == -1 &&
r2[p.method](p.EndToEnd, r1) == -1 &&
r2[p.method](p.StartToEnd, r1) == -1 &&
r2[p.method](p.EndToStart, r1) == -1);
}
function createRangeFromElement(el){
var rng = null;
if (document.body.createTextRange) {
rng = document.body.createTextRange();
rng.moveToElementText(el);
}
else
if (document.createRange) {
rng = document.createRange();
rng.selectNodeContents(el);
}
return rng;
}
}; |
Partager