summaryrefslogtreecommitdiff
path: root/lib/querypath/src/QueryPath/CSS/SimpleSelector.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/querypath/src/QueryPath/CSS/SimpleSelector.php')
-rw-r--r--lib/querypath/src/QueryPath/CSS/SimpleSelector.php138
1 files changed, 138 insertions, 0 deletions
diff --git a/lib/querypath/src/QueryPath/CSS/SimpleSelector.php b/lib/querypath/src/QueryPath/CSS/SimpleSelector.php
new file mode 100644
index 0000000..3fcc796
--- /dev/null
+++ b/lib/querypath/src/QueryPath/CSS/SimpleSelector.php
@@ -0,0 +1,138 @@
+<?php
+/** @file
+ *
+ * A simple selector.
+ *
+ */
+
+namespace QueryPath\CSS;
+
+/**
+ * Models a simple selector.
+ *
+ * CSS Selectors are composed of one or more simple selectors, where
+ * each simple selector may have any of the following components:
+ *
+ * - An element name (or wildcard *)
+ * - An ID (#foo)
+ * - One or more classes (.foo.bar)
+ * - One or more attribute matchers ([foo=bar])
+ * - One or more pseudo-classes (:foo)
+ * - One or more pseudo-elements (::first)
+ *
+ * For performance reasons, this object has been kept as sparse as
+ * possible.
+ *
+ * @since QueryPath 3.x
+ * @author M Butcher
+ *
+ */
+class SimpleSelector {
+
+ const adjacent = 1;
+ const directDescendant = 2;
+ const anotherSelector = 4;
+ const sibling = 8;
+ const anyDescendant = 16;
+
+ public $element;
+ public $ns;
+ public $id;
+ public $classes = array();
+ public $attributes = array();
+ public $pseudoClasses = array();
+ public $pseudoElements = array();
+ public $combinator;
+
+ public static function attributeOperator($code) {
+ switch($code) {
+ case EventHandler::containsWithSpace:
+ return '~=';
+ case EventHandler::containsWithHyphen:
+ return '|=';
+ case EventHandler::containsInString:
+ return '*=';
+ case EventHandler::beginsWith:
+ return '^=';
+ case EventHandler::endsWith:
+ return '$=';
+ default:
+ return '=';
+ }
+ }
+
+ public static function combinatorOperator($code) {
+ switch ($code) {
+ case self::adjacent:
+ return '+';
+ case self::directDescendant:
+ return '>';
+ case self::sibling:
+ return '~';
+ case self::anotherSelector:
+ return ', ';
+ case self::anyDescendant:
+ return ' ';
+ }
+ }
+
+ public function __construct() {
+ }
+
+ public function notEmpty() {
+ return !empty($element)
+ && !empty($id)
+ && !empty($classes)
+ && !empty($combinator)
+ && !empty($attributes)
+ && !empty($pseudoClasses)
+ && !empty($pseudoElements)
+ ;
+ }
+
+ public function __tostring() {
+ $buffer = array();
+ try {
+
+ if (!empty($this->ns)) {
+ $buffer[] = $this->ns; $buffer[] = '|';
+ }
+ if (!empty($this->element)) $buffer[] = $this->element;
+ if (!empty($this->id)) $buffer[] = '#' . $this->id;
+ if (!empty($this->attributes)) {
+ foreach ($this->attributes as $attr) {
+ $buffer[] = '[';
+ if(!empty($attr['ns'])) $buffer[] = $attr['ns'] . '|';
+ $buffer[] = $attr['name'];
+ if (!empty($attr['value'])) {
+ $buffer[] = self::attributeOperator($attr['op']);
+ $buffer[] = $attr['value'];
+ }
+ $buffer[] = ']';
+ }
+ }
+ if (!empty($this->pseudoClasses)) {
+ foreach ($this->pseudoClasses as $ps) {
+ $buffer[] = ':' . $ps['name'];
+ if (isset($ps['value'])) {
+ $buffer[] = '(' . $ps['value'] . ')';
+ }
+ }
+ }
+ foreach ($this->pseudoElements as $pe) {
+ $buffer[] = '::' . $pe;
+ }
+
+ if (!empty($this->combinator)) {
+ $buffer[] = self::combinatorOperator($this->combinator);
+ }
+
+ }
+ catch (\Exception $e) {
+ return $e->getMessage();
+ }
+
+ return implode('', $buffer);
+ }
+
+}