Created
August 3, 2008 07:24
-
-
Save cho45/3809 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// from http://www.joehewitt.com/blog/files/getElementsBySelector.js | |
// modified | |
function convertSelectorToXPath (rule, start) { | |
var regElement = /^([#.]?)([a-z0-9\\*_-]*)((\|)([a-z0-9\\*_-]*))?/i; | |
var regAttr1 = /^\[([^\]]*)\]/i; | |
var regAttr2 = /^\[\s*([^~=\s]+)\s*(~?=)\s*"([^"]+)"\s*\]/i; | |
var regPseudo = /^:([a-z_-])+/i; | |
var regCombinator = /^(\s*[>+\s])?/i; | |
var regComma = /^\s*,/i; | |
var index = 1; | |
var parts = [".//", "*"]; | |
var lastRule = null; | |
while (rule.length && rule != lastRule) { | |
lastRule = rule; | |
// Trim leading whitespace | |
rule = rule.replace(/^\s*|\s*$/g,""); | |
if (!rule.length) break; | |
// Match the element identifier | |
var m = regElement.exec(rule); | |
if (m) { | |
if (!m[1]) { | |
// XXXjoe Namespace ignored for now | |
if (m[5]) | |
parts[index] = m[5]; | |
else | |
parts[index] = m[2]; | |
} | |
else if (m[1] == '#') | |
parts.push("[@id='" + m[2] + "']"); | |
else if (m[1] == '.') | |
parts.push("[contains(concat(' ', @class, ' '), concat(' ', '" + m[2] + "', ' '))]"); | |
rule = rule.substr(m[0].length); | |
} | |
// Match attribute selectors | |
m = regAttr2.exec(rule); | |
if (m) { | |
if (m[2] == "~=") | |
parts.push("[contains(concat(' ', " + m[1] + ", ' '), concat(' ', '" + m[2] + "', ' '))]"); | |
else | |
parts.push("[@" + m[1] + "='" + m[3] + "']"); | |
rule = rule.substr(m[0].length); | |
} else { | |
m = regAttr1.exec(rule); | |
if (m) { | |
parts.push("[@" + m[1] + "]"); | |
rule = rule.substr(m[0].length); | |
} | |
} | |
// Skip over pseudo-classes and pseudo-elements, which are of no use to us | |
m = regPseudo.exec(rule); | |
while (m) { | |
rule = rule.substr(m[0].length); | |
m = regPseudo.exec(rule); | |
} | |
// Match combinators | |
m = regCombinator.exec(rule); | |
if (m && m[0].length) { | |
if (m[0].indexOf(">") != -1) | |
parts.push("/"); | |
else if (m[0].indexOf("+") != -1) | |
parts.push("/following-sibling::"); | |
else | |
parts.push("//"); | |
index = parts.length; | |
parts.push("*"); | |
rule = rule.substr(m[0].length); | |
} | |
m = regComma.exec(rule); | |
if (m) { | |
parts.push(" | ", ".//", "*"); | |
index = parts.length-1; | |
rule = rule.substr(m[0].length); | |
} | |
} | |
var xpath = parts.join(""); | |
return xpath; | |
} | |
function $S (selector, context, type) { | |
var xpath = convertSelectorToXPath(selector); | |
return $X(xpath, context, type); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment