File "Element.php"
Full Path: /home/aiclgcwq/photonindustriespvt.com/wp-content/plugins/tenweb-speed-optimizer/vendor/imangazaliev/didom/src/DiDom/Element.php
File size: 10.12 KB
MIME-type: text/x-php
Charset: utf-8
<?php
declare(strict_types=1);
namespace DiDom;
use DiDom\Exceptions\InvalidSelectorException;
use DOMCdataSection;
use DOMComment;
use DOMDocument;
use DOMElement;
use DOMNode;
use DOMText;
use InvalidArgumentException;
use LogicException;
use RuntimeException;
class Element extends Node
{
/**
* @var ClassAttribute
*/
protected $classAttribute;
/**
* @var StyleAttribute
*/
protected $styleAttribute;
/**
* @param DOMElement|DOMText|DOMComment|DOMCdataSection|string $tagName The tag name of an element
* @param string|integer|float|null $value The value of an element
* @param array $attributes The attributes of an element
*/
public function __construct($tagName, $value = null, array $attributes = [])
{
if (is_string($tagName)) {
$document = new DOMDocument('1.0', 'UTF-8');
$node = $document->createElement($tagName);
$this->setNode($node);
} else {
$this->setNode($tagName);
}
if ($value !== null) {
$this->setValue($value);
}
foreach ($attributes as $attrName => $attrValue) {
$this->setAttribute($attrName, $attrValue);
}
}
/**
* Creates a new element.
*
* @param DOMNode|string $name The tag name of an element
* @param string|integer|float|null $value The value of an element
* @param array $attributes The attributes of an element
*
* @return Element
*/
public static function create($name, $value = null, array $attributes = []): self
{
return new Element($name, $value, $attributes);
}
/**
* Creates a new element node by CSS selector.
*
* @param string $selector
* @param string|null $value
* @param array $attributes
*
* @return Element
*
* @throws InvalidSelectorException
*/
public static function createBySelector(string $selector, ?string $value = null, array $attributes = []): self
{
return Document::create()->createElementBySelector($selector, $value, $attributes);
}
public function tagName(): string
{
return $this->node->tagName;
}
/**
* Checks that the node matches selector.
*
* @param string $selector CSS selector
* @param bool $strict
*
* @return bool
*
* @throws InvalidSelectorException if the selector is invalid
* @throws InvalidArgumentException if the tag name is not a string
* @throws RuntimeException if the tag name is not specified in strict mode
*/
public function matches(string $selector, bool $strict = false): bool
{
if ( ! $this->node instanceof DOMElement) {
return false;
}
if ($selector === '*') {
return true;
}
if ( ! $strict) {
$innerHtml = $this->html();
$html = "<root>$innerHtml</root>";
$selector = 'root > ' . trim($selector);
$document = new Document();
$document->loadHtml($html, LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED);
return $document->has($selector);
}
$segments = Query::getSegments($selector);
if ( ! array_key_exists('tag', $segments)) {
throw new RuntimeException(sprintf('Tag name must be specified in %s', $selector));
}
if ($segments['tag'] !== $this->tagName() && $segments['tag'] !== '*') {
return false;
}
$segments['id'] = array_key_exists('id', $segments) ? $segments['id'] : null;
if ($segments['id'] !== $this->getAttribute('id')) {
return false;
}
$classes = $this->hasAttribute('class') ? explode(' ', trim($this->getAttribute('class'))) : [];
$segments['classes'] = array_key_exists('classes', $segments) ? $segments['classes'] : [];
$diff1 = array_diff($segments['classes'], $classes);
$diff2 = array_diff($classes, $segments['classes']);
if (count($diff1) > 0 || count($diff2) > 0) {
return false;
}
$attributes = $this->attributes();
unset($attributes['id'], $attributes['class']);
$segments['attributes'] = array_key_exists('attributes', $segments) ? $segments['attributes'] : [];
$diff1 = array_diff_assoc($segments['attributes'], $attributes);
$diff2 = array_diff_assoc($attributes, $segments['attributes']);
// if the attributes are not equal
if (count($diff1) > 0 || count($diff2) > 0) {
return false;
}
return true;
}
/**
* Determine if an attribute exists on the element.
*
* @param string $name The name of an attribute
*
* @return bool
*/
public function hasAttribute(string $name): bool
{
return $this->node->hasAttribute($name);
}
/**
* Set an attribute on the element.
*
* @param string $name The name of an attribute
* @param string|integer|float $value The value of an attribute
*
* @return Element
*/
public function setAttribute(string $name, $value): Element
{
if (is_numeric($value)) {
$value = (string) $value;
}
if ( ! is_string($value)) {
throw new InvalidArgumentException(sprintf('%s expects parameter 2 to be string or null, %s given.', __METHOD__, (is_object($value) ? get_class($value) : gettype($value))));
}
$this->node->setAttribute($name, $value);
return $this;
}
/**
* Access to the element's attributes.
*
* @param string $name The name of an attribute
* @param string|null $default The value returned if the attribute doesn't exist
*
* @return string|null The value of an attribute or null if attribute doesn't exist
*/
public function getAttribute(string $name, ?string $default = null): ?string
{
if ($this->hasAttribute($name)) {
return $this->node->getAttribute($name);
}
return $default;
}
/**
* Unset an attribute on the element.
*
* @param string $name The name of an attribute
*
* @return Element
*/
public function removeAttribute(string $name): self
{
$this->node->removeAttribute($name);
return $this;
}
/**
* Unset all attributes of the element.
*
* @param string[] $preserved
*
* @return Element
*/
public function removeAllAttributes(array $preserved = []): self
{
if ( ! $this->node instanceof DOMElement) {
return $this;
}
foreach ($this->attributes() as $name => $value) {
if (in_array($name, $preserved, true)) {
continue;
}
$this->node->removeAttribute($name);
}
return $this;
}
/**
* Alias for getAttribute and setAttribute methods.
*
* @param string $name The name of an attribute
* @param string|null $value The value that will be returned an attribute doesn't exist
*
* @return string|null|Element
*/
public function attr(string $name, ?string $value = null)
{
if ($value === null) {
return $this->getAttribute($name);
}
return $this->setAttribute($name, $value);
}
/**
* Returns the node attributes or null, if it is not DOMElement.
*
* @param string[] $names
*
* @return array|null
*/
public function attributes(array $names = null): ?array
{
if ( ! $this->node instanceof DOMElement) {
return null;
}
if ($names === null) {
$result = [];
foreach ($this->node->attributes as $name => $attribute) {
$result[$name] = $attribute->value;
}
return $result;
}
$result = [];
foreach ($this->node->attributes as $name => $attribute) {
if (in_array($name, $names, true)) {
$result[$name] = $attribute->value;
}
}
return $result;
}
/**
* @return ClassAttribute
*
* @throws LogicException if the node is not an instance of DOMElement
*/
public function classes(): ClassAttribute
{
if ($this->classAttribute !== null) {
return $this->classAttribute;
}
if ( ! $this->isElementNode()) {
throw new LogicException('Class attribute is available only for element nodes.');
}
$this->classAttribute = new ClassAttribute($this);
return $this->classAttribute;
}
/**
* @return StyleAttribute
*
* @throws LogicException if the node is not an instance of DOMElement
*/
public function style(): StyleAttribute
{
if ($this->styleAttribute !== null) {
return $this->styleAttribute;
}
if ( ! $this->isElementNode()) {
throw new LogicException('Style attribute is available only for element nodes.');
}
$this->styleAttribute = new StyleAttribute($this);
return $this->styleAttribute;
}
/**
* Dynamically set an attribute on the element.
*
* @param string $name The name of an attribute
* @param string|integer|float $value The value of an attribute
*
* @return Element
*/
public function __set(string $name, $value)
{
return $this->setAttribute($name, $value);
}
/**
* Dynamically access the element's attributes.
*
* @param string $name The name of an attribute
*
* @return string|null
*/
public function __get(string $name): ?string
{
return $this->getAttribute($name);
}
/**
* Determine if an attribute exists on the element.
*
* @param string $name The attribute name
*
* @return bool
*/
public function __isset(string $name): bool
{
return $this->hasAttribute($name);
}
/**
* Unset an attribute on the model.
*
* @param string $name The name of an attribute
*/
public function __unset(string $name)
{
$this->removeAttribute($name);
}
}