<?php
require_once dirname(__DIR__) . "/css-parser/css-element.php";
require_once dirname(__DIR__) . "/css-parser/css-factor.php";
require_once dirname(__DIR__) . "/css-parser/css-helper.php";
require_once dirname(__DIR__) . "/css-parser/filters/css-filter.php";
class CSSTerm {
/**
* List of factors.
* @var array(CSSFactor, ...)
*/
private $factors = array();
/**
* Adds a factor.
* @param CSSFactor $factor
*/
public function addFactor($factor) {
array_push($this->factors, $factor);
}
/**
* Filters the children of a given node.
* @param DOMNode $node
* @return array(DOMElement, ...)
*/
public function filter($node) {
$ret = array();
$items = array($node);
foreach ($this->factors as $factor) {
$ret = $this->getNodesFromListByFactor($items, $factor);
$items = $ret;
}
return $ret;
}
/**
* Searches nodes from a list by a given factor.
* @param array(DOMNode, ...) $nodes
* @param CSSFactor, $factor
* @return array(DOMElement, ...)
*/
private function getNodesFromListByFactor($nodes, $factor) {
$ret = array();
foreach ($nodes as $node) {
$items = $this->getNodesByFactor($node, $factor);
$ret = CSSHelper::mergeNodes($ret, $items);
}
return $ret;
}
/**
* Searches nodes by a given factor.
* @param DOMNode $node
* @param CSSFactor $factor
* @return array(DOMElement, ...)
*/
private function getNodesByFactor($node, $factor) {
$ret = array();
$element = $factor->getElement();
$op = $factor->getOperator();
if ($op == CSSFactor::DESCENDANT_OPERATOR) {
$ret = $this->getDescendantNodesByElement($node, $element);
} else
if ($op == CSSFactor::ADJACENT_OPERATOR) {
$ret = $this->getAdjacentNodesByElement($node, $element);
} else
if ($op == CSSFactor::CHILD_OPERATOR) {
$ret = $this->getChildNodesByElement($node, $element);
}
return $ret;
}
/**
* Searches descendant nodes by a given element.
* @param DOMNode $node
* @param CSSElement $element
* @return array(DOMElement, ...)
*/
private function getDescendantNodesByElement($node, $element) {
$ret = array();
$items = CSSHelper::getElementsByTagName($node, $element->getTagName());
foreach ($items as $item) {
if ($element->match($item)) {
array_push($ret, $item);
}
}
return $ret;
}
/**
* Searches adjacent nodes by a given element.
* @param DOMNode $node
* @param CSSElement $element
* @return array(DOMElement, ...)
*/
private function getAdjacentNodesByElement($node, $element) {
$ret = array();
$item = CSSHelper::getNextSiblingElement($node);
if ($item && $element->match($item)) {
$ret = array($item);
}
return $ret;
}
/**
* Searches child nodes by a given element.
* @param DOMNode $node
* @param CSSElement $elem
* @return array(DOMElement, ...)
*/
private function getChildNodesByElement($node, $element) {
$ret = array();
$items = CSSHelper::getChildElements($node);
foreach ($items as $item) {
if ($element->match($item)) {
array_push($ret, $item);
}
}
return $ret;
}
}
|