loadHTML($html); } } /** * Add attributes to the node * * @param DOMElement $node * @param array $attributes key-value paired attributes * * @since 1.0.0 */ public function add_attributes(&$node, $attributes) { foreach ($attributes as $name => $value) { $node->setAttribute($name, $value); } } /** * Add attributes to the node * * @param DOMElement $node * @param array $attributes key-value paired attributes * * @since 1.0.0 */ public function remove_attributes(&$node, $attributes) { foreach ($attributes as $name) { $node->removeAttribute($name); } } /** * Create a HTML Node * * @param string $tag node tag name * @param array $attributes key-value paired attributes * * @since 1.0.0 * * @return DOMElement */ public function create_node($tag, $attributes) { $node = $this->createElement($tag); $this->add_attributes($node, $attributes); return $node; } /** * Returns body * * @since 1.0.0 * * @return \DOMNode */ public function get_body_node() { return $this->getElementsByTagName('body')->item(0); } /** * Remove
tag and return body inner html * * @since 1.0.0 * * @param bool $body_element return just body elements * * @return string body tag inner HTML */ public function get_content($body_element = true) { if( $body_element ) { if( preg_match('#<\s*body[^>]*>(.+)<\s*/\s*body\s*>#isx', $this->saveHTML(), $match) ) { return $match[1]; } return ''; } return $this->saveHTML(); } /** * * Get attributes of the element * * @param DOMElement $node * * @since 1.0.0 * * @return array key-value paired attributes */ public static function get_node_attributes($node) { $attributes = array(); foreach( $node->attributes as $attribute ) { $attributes[$attribute->nodeName] = $attribute->nodeValue; } return $attributes; } /** * Replace node with new node * * @param DOMElement $node2replace a node to replace with * @param string $new_tag new node tag name * @param array $new_attributes key-value paired attributes * * @since 1.0.0 * * @return DOMNode The old node or false if an error occur. */ public function replace_node( $node2replace, $new_tag, $new_attributes ) { $new_node = $this->create_node( $new_tag, $new_attributes ); return $node2replace->parentNode->replaceChild( $new_node, $node2replace ); } /** * Todo: filter attributes * * @param array $attributes key-value paired attributes * * @since 1.0.0 * * @return array */ public function filter_attributes($attributes) { if( isset( $attributes['width'] ) ) { // sanitize width attribute value $attributes['width'] = Amp_WP_Content_Sanitizer::sanitize_dimension($attributes['width'], 'width'); } if( isset( $attributes['height'] ) ) { // sanitize height attribute value $attributes['height'] = Amp_WP_Content_Sanitizer::sanitize_dimension($attributes['height'], 'height'); } return $attributes; } /** * Load HTML from a string * @link http://php.net/manual/domdocument.loadhtml.ph * * @param string $html The HTML string * @param null|int $options - nothing! just for prevent trigger PHP Strict warning! * @param bool $wrap_body_tag wrap content into html>body tag * * @return bool true on success or false on failure. * @since 1.0.0 */ public function loadHTML($html, $options = null, $wrap_body_tag = true) { $prev = libxml_use_internal_errors(true); if ($wrap_body_tag) { parent::loadHTML('' . $html . ''); } else { $options = 0; if (defined('LIBXML_HTML_NODEFDTD')) { // Libxml >= 2.7.8 $options |= LIBXML_HTML_NODEFDTD; } if (defined('LIBXML_HTML_NOIMPLIED')) { // Libxml >= 2.7.7 $options |= LIBXML_HTML_NOIMPLIED; } if ($options) { parent::loadHTML($html, $options); } else { // support for old php version parent::loadHTML($html); } } libxml_use_internal_errors($prev); libxml_clear_errors(); } /** * Whether to check $node is empty * * @param DOMElement $node * * @since 1.0.0 * * @return bool */ public static function is_node_empty($node) { return 0 === $node->childNodes->length && empty( $node->textContent ); } /** * Get Single Children Element * * @param DOMElement $node * @param string $tag_name HTML Tag Name * @param array $required_atts * * @return bool|DOMElement DOMElement on success or false on failure * @since 1.0.0 */ public static function child($node, $tag_name, $required_atts = array()) { if( empty( $node->childNodes ) ) { return false; } $tag_name = strtolower($tag_name); /** * @var DOMElement $child_node */ foreach ($node->childNodes as $child_node) { if ($tag_name === $child_node->tagName) { foreach ($required_atts as $attr) { if (!$child_node->hasAttribute($attr)) { continue 2; } } return $child_node; } } return false; } /** * Rename element tag name * * @param DOMElement $element * @param string $newName * * @see http://stackoverflow.com/questions/12463550/rename-an-xml-node-using-php * * @since 1.0.0 */ public static function renameElement($element, $newName) { $newElement = $element->ownerDocument->createElement($newName); $parentElement = $element->parentNode; $parentElement->insertBefore($newElement, $element); $childNodes = $element->childNodes; while ($childNodes->length > 0) { $newElement->appendChild($childNodes->item(0)); } $attributes = $element->attributes; while ($attributes->length > 0) { $attribute = $attributes->item(0); if (!is_null($attribute->namespaceURI)) { $newElement->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:' . $attribute->prefix, $attribute->namespaceURI); } $newElement->setAttributeNode($attribute); } $parentElement->removeChild($element); } /** * Append Given HTML into the Element. * * @param DOMElement $element * @param string $html * * @since 1.2.1 */ public static function set_inner_HTML( $element, $html ) { $fragment = $element->ownerDocument->createDocumentFragment(); $fragment->appendXML( $html ); while( $element->hasChildNodes() ) { $element->removeChild( $element->firstChild ); } $element->appendChild( $fragment ); } /** * Replace Element With Given HTML. * * @param DOMElement $element * @param string $html * * @since 1.2.1 */ public static function set_outer_HTML( $element, $html ) { $fragment = $element->ownerDocument->createDocumentFragment(); $fragment->appendXML( $html ); if( $element->parentNode ) { $element->parentNode->appendChild( $fragment ); } while( $element->parentNode && $element->parentNode->hasChildNodes() ) { $element->parentNode->removeChild( $element->parentNode->firstChild ); } } }