Skip to content

Commit 4ec096b

Browse files
committed
moving libs from data tables repo
0 parents  commit 4ec096b

File tree

2 files changed

+474
-0
lines changed

2 files changed

+474
-0
lines changed

css2xpath.js

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/** version 0.1 2009-04-30
2+
* @author Andrea Giammarchi
3+
* @license Mit Style License
4+
* @project http://code.google.com/p/css2xpath/
5+
*/
6+
7+
/** css2xpath - generic CSS to XPath selector transformer
8+
* @author Andrea Giammarchi
9+
* @license Mit Style License
10+
* @blog http://webreflection.blogspot.com/
11+
* @project http://code.google.com/p/css2xpath/
12+
* @version 0.1 - Converts correctly every SlickSpeed CSS selector [http://mootools.net/slickspeed/]
13+
* @note stand alone vice-versa subproject [http://code.google.com/p/css2xpath/]
14+
* @info http://www.w3.org/TR/CSS2/selector.html
15+
* @credits some tips from Aristotle Pagaltzis [http://plasmasturm.org/log/444/]
16+
*/
17+
css2xpath = (function(){
18+
var re = [
19+
// add @ for attribs
20+
/\[([^\]~\$\*\^\|\!]+)(=[^\]]+)?\]/g, "[@$1$2]",
21+
// multiple queries
22+
/\s*,\s*/g, "|",
23+
// , + ~ >
24+
/\s*(\+|~|>)\s*/g, "$1",
25+
//* ~ + >
26+
/([a-zA-Z0-9\_\-\*])~([a-zA-Z0-9\_\-\*])/g, "$1/following-sibling::$2",
27+
/([a-zA-Z0-9\_\-\*])\+([a-zA-Z0-9\_\-\*])/g, "$1/following-sibling::*[1]/self::$2",
28+
/([a-zA-Z0-9\_\-\*])>([a-zA-Z0-9\_\-\*])/g, "$1/$2",
29+
// all unescaped stuff escaped
30+
/\[([^=]+)=([^'|"][^\]]*)\]/g, "[$1='$2']",
31+
// all descendant or self to //
32+
/(^|[^a-zA-Z0-9\_\-\*])(#|\.)([a-zA-Z0-9\_\-]+)/g, "$1*$2$3",
33+
/([\>\+\|\~\,\s])([a-zA-Z\*]+)/g, '$1//$2',
34+
/\s+\/\//g, '//',
35+
// :first-child
36+
/([a-zA-Z0-9\_\-\*]+):first-child/g, "*[1]/self::$1",
37+
// :last-child
38+
/([a-zA-Z0-9\_\-\*]+):last-child/g, "$1[not(following-sibling::*)]",
39+
// :only-child
40+
/([a-zA-Z0-9\_\-\*]+):only-child/g, "*[last()=1]/self::$1",
41+
// :empty
42+
/([a-zA-Z0-9\_\-\*]+):empty/g, "$1[not(*) and not(normalize-space())]",
43+
// :not
44+
/([a-zA-Z0-9\_\-\*]+):not\(([^\)]*)\)/g, function(s, a, b){return a.concat("[not(", css2xpath(b).replace(/^[^\[]+\[([^\]]*)\].*$/g, "$1"), ")]");},
45+
// :nth-child
46+
/([a-zA-Z0-9\_\-\*]+):nth-child\(([^\)]*)\)/g, function(s, a, b){
47+
switch(b){
48+
case "n":
49+
return a;
50+
case "even":
51+
return "*[position() mod 2=0 and position()>=0]/self::" + a;
52+
case "odd":
53+
return a + "[(count(preceding-sibling::*) + 1) mod 2=1]";
54+
default:
55+
b = (b || "0").replace(/^([0-9]*)n.*?([0-9]*)$/, "$1+$2").split("+");
56+
b[1] = b[1] || "0";
57+
return "*[(position()-".concat(b[1], ") mod ", b[0], "=0 and position()>=", b[1], "]/self::", a);
58+
}
59+
},
60+
// :contains(selectors)
61+
/:contains\(([^\)]*)\)/g, function(s, a){
62+
/*return "[contains(css:lower-case(string(.)),'" + a.toLowerCase() + "')]"; // it does not work in firefox 3*/
63+
return "[contains(string(.),'" + a + "')]";
64+
},
65+
// |= attrib
66+
/\[([a-zA-Z0-9\_\-]+)\|=([^\]]+)\]/g, "[@$1=$2 or starts-with(@$1,concat($2,'-'))]",
67+
// *= attrib
68+
/\[([a-zA-Z0-9\_\-]+)\*=([^\]]+)\]/g, "[contains(@$1,$2)]",
69+
// ~= attrib
70+
/\[([a-zA-Z0-9\_\-]+)~=([^\]]+)\]/g, "[contains(concat(' ',normalize-space(@$1),' '),concat(' ',$2,' '))]",
71+
// ^= attrib
72+
/\[([a-zA-Z0-9\_\-]+)\^=([^\]]+)\]/g, "[starts-with(@$1,$2)]",
73+
// $= attrib
74+
/\[([a-zA-Z0-9\_\-]+)\$=([^\]]+)\]/g, function(s, a, b){return "[substring(@".concat(a, ",string-length(@", a, ")-", b.length - 3, ")=", b, "]");},
75+
// != attrib
76+
/\[([a-zA-Z0-9\_\-]+)\!=([^\]]+)\]/g, "[not(@$1) or @$1!=$2]",
77+
// ids and classes
78+
/#([a-zA-Z0-9\_\-]+)/g, "[@id='$1']",
79+
/\.([a-zA-Z0-9\_\-]+)/g, "[contains(concat(' ',normalize-space(@class),' '),' $1 ')]",
80+
// normalize multiple filters
81+
/\]\[([^\]]+)/g, " and ($1)"
82+
],
83+
length = re.length
84+
;
85+
return function css2xpath(s){
86+
var i = 0;
87+
while(i < length)
88+
s = s.replace(re[i++], re[i++]);
89+
return "//" + s;
90+
};
91+
})();

0 commit comments

Comments
 (0)