From 9a9c04512e5dcb77c7fe5d850e3f2a0250cc160e Mon Sep 17 00:00:00 2001 From: emkael Date: Wed, 18 Jan 2017 20:07:16 +0100 Subject: * Motor Sport Magazine feed provider --- .../src/QueryPath/CSS/DOMTraverser/Util.php | 139 +++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 lib/querypath/src/QueryPath/CSS/DOMTraverser/Util.php (limited to 'lib/querypath/src/QueryPath/CSS/DOMTraverser/Util.php') diff --git a/lib/querypath/src/QueryPath/CSS/DOMTraverser/Util.php b/lib/querypath/src/QueryPath/CSS/DOMTraverser/Util.php new file mode 100644 index 0000000..ec01d8f --- /dev/null +++ b/lib/querypath/src/QueryPath/CSS/DOMTraverser/Util.php @@ -0,0 +1,139 @@ +hasAttribute($name)) { + return FALSE; + } + + if (is_null($value)) { + return TRUE; + } + + return self::matchesAttributeValue($value, $node->getAttribute($name), $operation); + } + /** + * Check whether the given DOMElement has the given namespaced attribute. + */ + public static function matchesAttributeNS($node, $name, $nsuri, $value = NULL, $operation = EventHandler::isExactly) { + if (!$node->hasAttributeNS($nsuri, $name)) { + return FALSE; + } + + if (is_null($value)) { + return TRUE; + } + + return self::matchesAttributeValue($value, $node->getAttributeNS($nsuri, $name), $operation); + } + + /** + * Check for attr value matches based on an operation. + */ + public static function matchesAttributeValue($needle, $haystack, $operation) { + + if (strlen($haystack) < strlen($needle)) return FALSE; + + // According to the spec: + // "The case-sensitivity of attribute names in selectors depends on the document language." + // (6.3.2) + // To which I say, "huh?". We assume case sensitivity. + switch ($operation) { + case EventHandler::isExactly: + return $needle == $haystack; + case EventHandler::containsWithSpace: + // XXX: This needs testing! + return preg_match('/\b/', $haystack) == 1; + //return in_array($needle, explode(' ', $haystack)); + case EventHandler::containsWithHyphen: + return in_array($needle, explode('-', $haystack)); + case EventHandler::containsInString: + return strpos($haystack, $needle) !== FALSE; + case EventHandler::beginsWith: + return strpos($haystack, $needle) === 0; + case EventHandler::endsWith: + //return strrpos($haystack, $needle) === strlen($needle) - 1; + return preg_match('/' . $needle . '$/', $haystack) == 1; + } + return FALSE; // Shouldn't be able to get here. + } + + /** + * Remove leading and trailing quotes. + */ + public static function removeQuotes($str) { + $f = substr($str, 0, 1); + $l = substr($str, -1); + if ($f === $l && ($f == '"' || $f == "'")) { + $str = substr($str, 1, -1); + } + return $str; + } + + /** + * Parse an an+b rule for CSS pseudo-classes. + * + * Invalid rules return `array(0, 0)`. This is per the spec. + * + * @param $rule + * Some rule in the an+b format. + * @retval array + * `array($aVal, $bVal)` of the two values. + */ + public static function parseAnB($rule) { + if ($rule == 'even') { + return array(2, 0); + } + elseif ($rule == 'odd') { + return array(2, 1); + } + elseif ($rule == 'n') { + return array(1, 0); + } + elseif (is_numeric($rule)) { + return array(0, (int)$rule); + } + + $regex = '/^\s*([+\-]?[0-9]*)n\s*([+\-]?)\s*([0-9]*)\s*$/'; + $matches = array(); + $res = preg_match($regex, $rule, $matches); + + // If it doesn't parse, return 0, 0. + if (!$res) { + return array(0, 0); + } + + $aVal = isset($matches[1]) ? $matches[1] : 1; + if ($aVal == '-') { + $aVal = -1; + } + else { + $aVal = (int) $aVal; + } + + $bVal = 0; + if (isset($matches[3])) { + $bVal = (int) $matches[3]; + if (isset($matches[2]) && $matches[2] == '-') { + $bVal *= -1; + } + } + return array($aVal, $bVal); + } + +} -- cgit v1.2.3