Skip to content

Instantly share code, notes, and snippets.

@cou929
Created August 17, 2010 15:45
Show Gist options
  • Save cou929/530481 to your computer and use it in GitHub Desktop.
Save cou929/530481 to your computer and use it in GitHub Desktop.
/**
* toru.js
* Kosei Moriyama <cou929@gmail.com>
*
* Get selection area, traverse the area, obtain xpath of dom elements inside the area
* and send the xpath to torerundesu server.
*
* TODO:
* - Find cookies and check the user is logined or not.
* - Send results to the server.
* - Show selected area.
* - Build add-ons (future).
*/
javascript:(function(){
/*
* Make XPath from node
* http://ido.nu/kuma/2007/10/25/tiny-xpath-related-utilities-in-firebug/
*/
function xN(xpath, context) {
var snapshot = document.evaluate(xpath, context, null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
return snapshot.snapshotLength;
}
function nodePath(node) {
return ( node != document ? (
[nodePath(node.parentNode) , node.nodeName ].join('/') +
"[" + (xN('./preceding-sibling::' + node.nodeName, node) + 1) + "]"
) : '');
}
/*
* Remove empty node
* https://developer.mozilla.org/en/Whitespace_in_the_DOM
*/
function is_all_ws( nod ) {
return !(/[^\t\n\r ]/.test(nod.data));
}
function is_ignorable( nod ) {
return ( nod.nodeType == 8) || // comment node
( (nod.nodeType == 3) && is_all_ws(nod) ); // text node && all white space
}
/**
* Get xpath from selection area
* @param selection The selection object
* @return An array which contains set of XPath
* which is leaf of dom tree contained by the selection.
*/
function getXPath(selection) {
var range = selection.getRangeAt(0);
var root = range.commonAncestorContainer;
var inside_nodes = [];
var xpath = [];
trv(root);
for (var i=0, node; node=inside_nodes[i]; i++) {
var cur = node;
while (cur.nodeType === 3)
cur = node.parentNode;
xpath.push(nodePath(cur));
}
return xpath;
/**
* Traverse dom tree by dfs, and find selected nodes.
*
* @param node The node which is currently searched.
* @return Nothing is returned.
* The function stores results into 'inside_nodes'
*/
function trv(node) {
if (is_ignorable(node)) && return;
if (selection.containsNode(node, false))
inside_nodes.push(node);
else
for (var i=0, n; n=node.childNodes[i]; i++)
trv(n);
}
}
/*
* Application code
*/
var selection = window.getSelection();
if (!selection.isCollapsed) {
var xpath = getXPath(selection);
alert(xpath);
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment