| Current Path : /var/www/iplanru/data/www/www.i-plan.ru/templates/yoo_everest/warp/src/Warp/Dom/ | 
| Current File : /var/www/iplanru/data/www/www.i-plan.ru/templates/yoo_everest/warp/src/Warp/Dom/Element.php | 
<?php
/**
* @package   Warp Theme Framework
* @author    YOOtheme http://www.yootheme.com
* @copyright Copyright (C) YOOtheme GmbH
* @license   http://www.gnu.org/licenses/gpl.html GNU/GPL
*/
namespace Warp\Dom;
/**
 * DOM element class with extended attributes and functions.
 */
class Element extends \DOMElement
{
    public function first($query)
    {
        if ($matches = $this->find($query)) {
            if ($matches->length) {
                return $matches->item(0);
            }
        }
        return null;
    }
    public function find($query)
    {
        return $this->query(CssSelector::toXPath($query, 'descendant::'));
    }
    public function query($expression)
    {
        return $this->ownerDocument->xpath()->query($expression, $this);
    }
    public function parent()
    {
        return $this->parentNode;
    }
    public function next()
    {
        $sibling = $this->nextSibling;
        do {
            if ($sibling->nodeType == XML_ELEMENT_NODE) {
                break;
            }
        } while ($sibling = $sibling->nextSibling);
        return $sibling;
    }
    public function prev()
    {
        $sibling = $this->previousSibling;
        do {
            if ($sibling->nodeType == XML_ELEMENT_NODE) {
                break;
            }
        } while ($sibling = $sibling->previousSibling);
        return $sibling;
    }
    public function hasChildren()
    {
        return $this->hasChildNodes();
    }
    public function children($query = null)
    {
        $children = array();
        if (!$this->hasChildren()) {
            return $children;
        }
        if ($query == null) {
            foreach ($this->childNodes as $child) {
                if ($child->nodeType == XML_ELEMENT_NODE) {
                    $children[] = $child;
                }
            }
            return $children;
        }
        return $this->query(CssSelector::toXPath($query, 'child::'));
    }
    public function removeChildren()
    {
        while ($child = $this->firstChild) {
            $this->removeChild($child);
        }
        return $this;
    }
    public function before($data)
    {
        $data = $this->prepareInsert($data);
        $this->parentNode->insertBefore($data, $this);
        return $this;
    }
    public function after($data)
    {
        $data = $this->prepareInsert($data);
        if (isset($this->nextSibling)) {
            $this->parentNode->insertBefore($data, $this->nextSibling);
        } else {
            $this->parentNode->appendChild($data);
        }
        return $this;
    }
    public function prepend($data)
    {
        $data = $this->prepareInsert($data);
        if (isset($data)) {
            if ($this->hasChildren()) {
                $this->insertBefore($data, $this->firstChild);
            } else {
                $this->appendChild($data);
            }
        }
        return $this;
    }
    public function append($data)
    {
        $data = $this->prepareInsert($data);
        if (isset($data)) {
            $this->appendChild($data);
        }
        return $this;
    }
    public function replaceWith($data)
    {
        $data = $this->prepareInsert($data);
        if (isset($data)) {
            $this->parent()->replaceChild($data, $this);
        }
        return $data;
    }
    public function wrap($data)
    {
        $data = $this->prepareInsert($data);
        if (empty($data)) {
            return $this;
        }
        self::wrapNode($this, $data);
        return $this;
    }
    public function text($text = null)
    {
        if (isset($text)) {
            $this->removeChildren();
            $this->appendChild($this->ownerDocument->createTextNode($text));
            return $this;
        }
        return $this->textContent;
    }
    public function html($markup = null)
    {
        if (isset($markup)) {
            $this->removeChildren();
            $this->append($markup);
            return $this;
        }
        // fix selfclosing tags
        if (false !== $html = $this->ownerDocument->saveXML($this)) {
            $html = preg_replace('#(<(div|span|i)(\s[^>]*)?)/>#i', '$1></$2>', $html);
        }
        return $html;
    }
    public function tag()
    {
        return $this->tagName;
    }
    public function val($value = null)
    {
        if (isset($value)) {
            return $this->attr('value', $value);
        }
        return $this->attr('value');
    }
    public function hasClass($class)
    {
        return self::attrClass('has', $this, $class);
    }
    public function addClass($class)
    {
        return self::attrClass('add', $this, $class);
    }
    public function removeClass($class)
    {
        return self::attrClass('remove', $this, $class);
    }
    public function toggleClass($class)
    {
        return self::attrClass('toggle', $this, $class);
    }
    public function attr($name = null, $value = null)
    {
        if (is_null($name)) {
            $attributes = array();
            foreach ($this->attributes as $name => $node) {
                $attributes[$name] = $node->value;
            }
            return $attributes;
        }
        if (isset($value)) {
            $this->setAttribute($name, $value);
            return $this;
        }
        return $this->getAttribute($name);
    }
    public function removeAttr($name)
    {
        $this->removeAttribute($name);
        return $this;
    }
    protected function prepareInsert($item)
    {
        if (empty($item)) {
            return;
        }
        if (is_string($item)) {
            $item = Entities::replaceAllEntities($item);
            $frag = $this->ownerDocument->createDocumentFragment();
            try {
                $frag->appendXML($item);
            } catch (Exception $e) {}
            return $frag;
        }
        if ($item instanceof \DOMNode) {
            if ($item->ownerDocument !== $this->ownerDocument) {
                return $this->ownerDocument->importNode($item, true);
            }
            return $item;
        }
    }
    protected static function wrapNode(\DOMNode $node, \DOMNode $wrapper)
    {
        if ($wrapper->hasChildNodes()) {
            $deepest = self::deepestNode($wrapper);
            $wrapper = $deepest[0];
        }
        $parent = $node->parentNode;
        $parent->insertBefore($wrapper, $node);
        $wrapper->appendChild($parent->removeChild($node));
    }
    protected static function deepestNode(\DOMNode $node, $depth = 0, $current = null, &$deepest = null)
    {
        if (!isset($current)) $current = array($node);
        if (!isset($deepest)) $deepest = $depth;
        if ($node->hasChildNodes()) {
            foreach ($node->childNodes as $child) {
                if ($child->nodeType === XML_ELEMENT_NODE) {
                    $current = self::deepestNode($child, $depth + 1, $current, $deepest);
                }
            }
        } elseif ($depth > $deepest) {
            $current = array($node);
            $deepest = $depth;
        } elseif ($depth === $deepest) {
            $current[] = $node;
        }
        return $current;
    }
    protected static function attrClass($action, \DOMNode $node, $class)
    {
        $classes = $node->getAttribute('class');
        $found   = stripos($classes, $class) !== false && in_array(strtolower($class), explode(' ', strtolower($classes)));
        if ($action == 'has') {
            return $found;
        }
        if ($action == 'toggle') {
            $action = $found ? 'remove' : 'add';
        }
        if ($action == 'add' && !$found) {
            $node->setAttribute('class', trim(preg_replace('/\s{2,}/i', ' ', $classes.' '.$class)));
        }
        if ($action == 'remove' && $found) {
            $classes = trim(preg_replace('/\s{2,}/i', ' ', preg_replace('/(^|\s)'.preg_quote($class, '/').'(?:\s|$)/i', ' ', $classes)));
            if ($classes !== '') {
                $node->setAttribute('class', $classes);
            } else {
                $node->removeAttribute('class');
            }
        }
        return $node;
    }
}