|
Server : LiteSpeed System : Linux host 5.15.0-161-generic #171-Ubuntu SMP Sat Oct 11 08:17:01 UTC 2025 x86_64 User : idnco5810 ( 1093) PHP Version : 8.2.29 Disable Function : NONE Directory : /home/idn98.co/public_html/wp-content/plugins/amp/includes/embeds/ |
Upload File : |
<?php
/**
* Class AMP_Base_Embed_Handler
*
* Used by some children.
*
* @package AMP
*/
use AmpProject\Dom\Document;
use AmpProject\Dom\Element;
use AmpProject\Html\Attribute;
use AmpProject\Html\Tag;
/**
* Class AMP_Base_Embed_Handler
*
* @since 0.2
*/
abstract class AMP_Base_Embed_Handler {
/**
* Default width.
*
* In some cases, this may be the string 'auto' when a fixed-height layout is used.
*
* @var int|string
*/
protected $DEFAULT_WIDTH = 600;
/**
* Default height.
*
* @var int
*/
protected $DEFAULT_HEIGHT = 480;
/**
* Default arguments.
*
* @var array
*/
protected $args = [];
/**
* Whether or not conversion was completed.
*
* @var boolean
*/
protected $did_convert_elements = false;
/**
* Registers embed.
*/
abstract public function register_embed();
/**
* Unregisters embed.
*/
abstract public function unregister_embed();
/**
* Constructor.
*
* @param array $args Height and width for embed.
*/
public function __construct( $args = [] ) {
$this->args = wp_parse_args(
$args,
[
'width' => $this->DEFAULT_WIDTH,
'height' => $this->DEFAULT_HEIGHT,
]
);
}
/**
* Get mapping of AMP component names to AMP script URLs.
*
* This is normally no longer needed because the validating
* sanitizer will automatically detect the need for them via
* the spec.
*
* @see AMP_Tag_And_Attribute_Sanitizer::get_scripts()
* @return array Scripts.
*/
public function get_scripts() {
return [];
}
/**
* Get regex pattern for matching HTML attributes from a given tag name.
*
* @since 1.5.0
* @todo This does not currently work with single-quoted attribute values or non-quoted attributes.
*
* @param string $html HTML source haystack.
* @param string $tag_name Tag name.
* @param string[] $attribute_names Attribute names.
* @return string[]|null Matched attributes, or null if the element was not matched at all.
*/
protected function match_element_attributes( $html, $tag_name, $attribute_names ) {
$pattern = sprintf(
'/<%s%s/',
preg_quote( $tag_name, '/' ),
implode(
'',
array_map(
static function ( $attr_name ) {
return sprintf( '(?=[^>]*?%1$s="(?P<%1$s>[^"]+)")?', preg_quote( $attr_name, '/' ) );
},
$attribute_names
)
)
);
if ( ! preg_match( $pattern, $html, $matches ) ) {
return null;
}
return wp_array_slice_assoc( $matches, $attribute_names );
}
/**
* Get all child elements of the specified element.
*
* @since 2.0.6
*
* @param DOMElement $node Element.
* @return DOMElement[] Array of child elements for specified element.
*/
protected function get_child_elements( DOMElement $node ) {
return array_filter(
iterator_to_array( $node->childNodes ),
static function ( DOMNode $child ) {
return $child instanceof DOMElement;
}
);
}
/**
* Replace an element's parent with itself if the parent is a <p> tag which has no attributes and has no other children.
*
* This usually happens while `wpautop()` processes the element.
*
* @since 2.0.6
* @see AMP_Tag_And_Attribute_Sanitizer::remove_node()
*
* @param DOMElement $node Node.
*/
protected function unwrap_p_element( DOMElement $node ) {
$parent_node = $node->parentNode;
if (
$parent_node instanceof DOMElement
&&
'p' === $parent_node->tagName
&&
false === $parent_node->hasAttributes()
&&
1 === count( $this->get_child_elements( $parent_node ) )
) {
$parent_node->parentNode->replaceChild( $node, $parent_node );
}
}
/**
* Removes the node's nearest `<script>` sibling with a `src` attribute containing the base `src` URL provided.
*
* @since 2.1
*
* @param DOMElement $node The DOMNode to whose sibling is the script to be removed.
* @param callable $match_callback Callback which is passed the script element to determine if it is a match.
*/
protected function maybe_remove_script_sibling( DOMElement $node, callable $match_callback ) {
$next_element_sibling = $node->nextSibling;
while ( $next_element_sibling && ! $next_element_sibling instanceof DOMElement ) {
$next_element_sibling = $next_element_sibling->nextSibling;
}
if ( ! $next_element_sibling instanceof DOMElement ) {
return;
}
// Handle case where script is immediately following.
if ( Tag::SCRIPT === $next_element_sibling->tagName && $match_callback( $next_element_sibling ) ) {
$next_element_sibling->parentNode->removeChild( $next_element_sibling );
return;
}
// Handle case where script is wrapped in paragraph by wpautop.
if ( 'p' === $next_element_sibling->tagName ) {
/** @var DOMElement[] $children_elements */
$children_elements = array_values(
array_filter(
iterator_to_array( $next_element_sibling->childNodes ),
static function ( DOMNode $child ) {
return $child instanceof DOMElement;
}
)
);
if (
1 === count( $children_elements )
&&
Tag::SCRIPT === $children_elements[0]->tagName
&&
$match_callback( $children_elements[0] )
) {
$next_element_sibling->parentNode->removeChild( $next_element_sibling );
}
}
}
/**
* Create overflow button element.
*
* @param Document $dom Document.
* @param string $text Button text (optional).
* @return Element Button element.
*/
protected function create_overflow_button_element( Document $dom, $text = null ) {
if ( ! $text ) {
$text = __( 'See more', 'amp' );
}
$overflow = $dom->createElement( Tag::BUTTON );
$overflow->setAttributeNode( $dom->createAttribute( Attribute::OVERFLOW ) );
$overflow->setAttribute( Attribute::TYPE, 'button' );
$overflow->textContent = $text;
return $overflow;
}
/**
* Create overflow button markup.
*
* @param string $text Button text (optional).
* @return string Button markup.
*/
protected function create_overflow_button_markup( $text = null ) {
if ( ! $text ) {
$text = __( 'See more', 'amp' );
}
return sprintf( '<button overflow type="button">%s</button>', esc_html( $text ) );
}
}