Uname: Linux webm005.cluster107.gra.hosting.ovh.net 5.15.167-ovh-vps-grsec-zfs-classid #1 SMP Tue Sep 17 08:14:20 UTC 2024 x86_64
User: 6036 (villadal)
Group: 100 (users)
Disabled functions: NONE
Safe mode: On[ PHPinfo ]
//home/villadal/www/wp-content/plugins/contact-form-7/includes/      ( Reset | Go to )
File Name: html-formatter.php
Edit
<?php

/**
 * Contact Form 7's class used for formatting HTML fragments.
 */
class WPCF7_HTMLFormatter {

    
// HTML component types.
    
const text 0;
    const 
start_tag 1;
    const 
end_tag 2;
    const 
comment 3;

    
/**
     * Tag name reserved for a custom HTML element used as a block placeholder.
     */
    
const placeholder_block 'placeholder:block';

    
/**
     * Tag name reserved for a custom HTML element used as an inline placeholder.
     */
    
const placeholder_inline 'placeholder:inline';

    
/**
     * The void elements in HTML.
     *
     * @link https://developer.mozilla.org/en-US/docs/Glossary/Void_element
     */
    
const void_elements = array(
        
'area''base''br''col''embed''hr''img''input',
        
'keygen''link''meta''param''source''track''wbr',
        
self::placeholder_blockself::placeholder_inline,
    );

    
/**
     * HTML elements that can contain flow content.
     */
    
const p_parent_elements = array(
        
'address''article''aside''blockquote''body''caption',
        
'dd''details''dialog''div''dt''fieldset''figcaption',
        
'figure''footer''form''header''li''main''nav',
        
'section''td''th',
    );

    
/**
     * HTML elements that can be neither the parent nor a child of
     * a paragraph element.
     */
    
const p_nonparent_elements = array(
        
'colgroup''dl''h1''h2''h3''h4''h5''h6''head',
        
'hgroup''html''legend''menu''ol''pre''style''summary',
        
'table''tbody''template''tfoot''thead''title''tr''ul',
    );

    
/**
     * HTML elements in the phrasing content category, plus non-phrasing
     * content elements that can be grandchildren of a paragraph element.
     */
    
const p_child_elements = array(
        
'a''abbr''area''audio''b''bdi''bdo''br''button',
        
'canvas''cite''code''data''datalist''del''dfn',
        
'em''embed''i''iframe''img''input''ins''kbd',
        
'keygen''label''link''map''mark''meta',
        
'meter''noscript''object''output''picture''progress',
        
'q''ruby''s''samp''script''select''slot''small',
        
'span''strong''sub''sup''textarea',
        
'time''u''var''video''wbr',
        
'optgroup''option''rp''rt'// non-phrasing grandchildren
        
self::placeholder_inline,
    );

    
/**
     * HTML elements that can contain phrasing content.
     */
    
const br_parent_elements = array(
        
'a''abbr''address''article''aside''audio''b''bdi',
        
'bdo''blockquote''button''canvas''caption''cite''code',
        
'data''datalist''dd''del''details''dfn''dialog''div',
        
'dt''em''fieldset''figcaption''figure''footer''form',
        
'h1''h2''h3''h4''h5''h6''header''i''ins''kbd',
        
'label''legend''li''main''map''mark''meter''nav',
        
'noscript''object''output''p''progress''q''rt',
        
'ruby''s''samp''section''slot''small''span''strong',
        
'sub''summary''sup''td''th''time''u''var',
        
'video',
    );


    
// Properties.
    
private $options = array();
    private 
$stacked_elements = array();
    private 
$output '';


    
/**
     * Constructor.
     */
    
public function __construct$args '' ) {
        
$this->options wp_parse_args$args, array(
            
'auto_br' => true,
            
'auto_indent' => true,
        ) );
    }


    
/**
     * Separates the given text into chunks of HTML. Each chunk must be an
     * associative array that includes 'position', 'type', and 'content' keys.
     *
     * @param string $input Text to be separated into chunks.
     * @return iterable Iterable of chunks.
     */
    
public function separate_into_chunks$input ) {
        
$input_bytelength strlen$input );
        
$position 0;

        while ( 
$position $input_bytelength ) {
            
$next_tag preg_match(
                
'/(?:<!--.*?-->|<(?:\/?)[a-z].*?>)/is',
                
$input,
                
$matches,
                
PREG_OFFSET_CAPTURE,
                
$position
            
);

            if ( ! 
$next_tag ) {
                yield array(
                    
'position' => $position,
                    
'type' => self::text,
                    
'content' => substr$input$position ),
                );

                break;
            }

            
$next_tag $matches[0][0];
            
$next_tag_position $matches[0][1];

            if ( 
$position $next_tag_position ) {
                yield array(
                    
'position' => $position,
                    
'type' => self::text,
                    
'content' => substr(
                        
$input,
                        
$position,
                        
$next_tag_position $position
                    
),
                );
            }

            if ( 
'<!' === substr$next_tag0) ) {
                
$next_tag_type self::comment;
            } elseif ( 
'</' === substr$next_tag0) ) {
                
$next_tag_type self::end_tag;
            } else {
                
$next_tag_type self::start_tag;
            }

            yield array(
                
'position' => $next_tag_position,
                
'type' => $next_tag_type,
                
'content' => substr(
                    
$input,
                    
$next_tag_position,
                    
strlen$next_tag )
                ),
            );

            
$position $next_tag_position strlen$next_tag );
        }
    }


    
/**
     * Normalizes content in each chunk. This may change the type and position
     * of the chunk.
     *
     * @param iterable $chunks The original chunks.
     * @return iterable Normalized chunks.
     */
    
public function pre_format$chunks ) {
        
$position 0;

        foreach ( 
$chunks as $chunk ) {
            
$chunk['position'] = $position;

            
// Standardize newline characters to "\n".
            
$chunk['content'] = str_replace(
                array( 
"\r\n""\r" ), "\n"$chunk['content']
            );

            if ( 
$chunk['type'] === self::start_tag ) {
                list( 
$chunk['content'] ) =
                    
self::normalize_start_tag$chunk['content'] );

                
// Replace <br /> by a line break.
                
if (
                    
$this->options['auto_br'] and
                    
preg_match'/^<br\s*\/?>$/i'$chunk['content'] )
                ) {
                    
$chunk['type'] = self::text;
                    
$chunk['content'] = "\n";
                }
            }

            yield 
$chunk;
            
$position self::calc_next_position$chunk );
        }
    }


    
/**
     * Concatenates neighboring text chunks to create a single chunk.
     *
     * @param iterable $chunks The original chunks.
     * @return iterable Processed chunks.
     */
    
public function concatenate_texts$chunks ) {
        
$position 0;
        
$text_left null;

        foreach ( 
$chunks as $chunk ) {
            
$chunk['position'] = $position;

            if ( 
$chunk['type'] === self::text ) {
                if ( isset( 
$text_left ) ) {
                    
$text_left['content'] .= $chunk['content'];
                } else {
                    
$text_left $chunk;
                }

                continue;
            }

            if ( isset( 
$text_left ) ) {
                yield 
$text_left;
                
$chunk['position'] = self::calc_next_position$text_left );
                
$text_left null;
            }

            yield 
$chunk;
            
$position self::calc_next_position$chunk );
        }

        if ( isset( 
$text_left ) ) {
            yield 
$text_left;
        }
    }


    
/**
     * Outputs formatted HTML based on the given chunks.
     *
     * @param iterable $chunks The original chunks.
     * @return string Formatted HTML.
     */
    
public function format$chunks ) {
        
$chunks $this->pre_format$chunks );
        
$chunks $this->concatenate_texts$chunks );

        
$this->output '';
        
$this->stacked_elements = array();

        foreach ( 
$chunks as $chunk ) {

            if ( 
$chunk['type'] === self::text ) {
                
$this->append_text$chunk['content'] );
            }

            if ( 
$chunk['type'] === self::start_tag ) {
                
$this->start_tag$chunk['content'] );
            }

            if ( 
$chunk['type'] === self::end_tag ) {
                
$this->end_tag$chunk['content'] );
            }

            if ( 
$chunk['type'] === self::comment ) {
                
$this->append_comment$chunk['content'] );
            }
        }

        
// Close all remaining tags.
        
$this->close_all_tags();

        return 
$this->output;
    }


    
/**
     * Appends a text node content to the output property.
     *
     * @param string $content Text node content.
     */
    
public function append_text$content ) {
        if ( 
$this->is_inside( array( 'pre''template' ) ) ) {
            
$this->output .= $content;
            return;
        }

        if (
            empty( 
$this->stacked_elements ) or
            
$this->has_parent'p' ) or
            
$this->has_parentself::p_parent_elements )
        ) {
            
// Close <p> if the content starts with multiple line breaks.
            
if ( preg_match'/^\s*\n\s*\n\s*/'$content ) ) {
                
$this->end_tag'p' );
            }

            
// Split up the contents into paragraphs, separated by double line breaks.
            
$paragraphs preg_split'/\s*\n\s*\n\s*/'$content );

            
$paragraphs array_filter$paragraphs, static function ( $paragraph ) {
                return 
'' !== trim$paragraph );
            } );

            
$paragraphs array_values$paragraphs );

            if ( 
$paragraphs ) {
                if ( 
$this->is_inside'p' ) ) {
                    
$paragraph array_shift$paragraphs );

                    
$paragraph self::normalize_paragraph(
                        
$paragraph,
                        
$this->options['auto_br']
                    );

                    
$this->output .= $paragraph;
                }

                foreach ( 
$paragraphs as $paragraph ) {
                    
$this->start_tag'p' );

                    
$paragraph ltrim$paragraph );

                    
$paragraph self::normalize_paragraph(
                        
$paragraph,
                        
$this->options['auto_br']
                    );

                    
$this->output .= $paragraph;
                }
            }

            
// Close <p> if the content ends with multiple line breaks.
            
if ( preg_match'/\s*\n\s*\n\s*$/'$content ) ) {
                
$this->end_tag'p' );
            }

            
// Cases where the content is a single line break.
            
if ( preg_match'/^\s*\n\s*$/'$content ) ) {
                
$auto_br $this->options['auto_br'] && $this->is_inside'p' );

                
$content self::normalize_paragraph$content$auto_br );

                
$this->output .= $content;
            }
        } else {
            
$auto_br $this->options['auto_br'] &&
                
$this->has_parentself::br_parent_elements );

            
$content self::normalize_paragraph$content$auto_br );

            
$this->output .= $content;
        }
    }


    
/**
     * Appends a start tag to the output property.
     *
     * @param string $tag A start tag.
     */
    
public function start_tag$tag ) {
        list( 
$tag$tag_name ) = self::normalize_start_tag$tag );

        if ( 
in_array$tag_nameself::p_child_elements ) ) {
            if (
                ! 
$this->is_inside'p' ) and
                ! 
$this->is_insideself::p_child_elements ) and
                ! 
$this->has_parentself::p_nonparent_elements )
            ) {
                
// Open <p> if it does not exist.
                
$this->start_tag'p' );
            }
        } elseif (
            
'p' === $tag_name or
            
in_array$tag_nameself::p_parent_elements ) or
            
in_array$tag_nameself::p_nonparent_elements )
        ) {
            
// Close <p> if it exists.
            
$this->end_tag'p' );
        }

        if ( 
'dd' === $tag_name or 'dt' === $tag_name ) {
            
// Close <dd> and <dt> if closing tag is omitted.
            
$this->end_tag'dd' );
            
$this->end_tag'dt' );
        }

        if ( 
'li' === $tag_name ) {
            
// Close <li> if closing tag is omitted.
            
$this->end_tag'li' );
        }

        if ( 
'optgroup' === $tag_name ) {
            
// Close <option> and <optgroup> if closing tag is omitted.
            
$this->end_tag'option' );
            
$this->end_tag'optgroup' );
        }

        if ( 
'option' === $tag_name ) {
            
// Close <option> if closing tag is omitted.
            
$this->end_tag'option' );
        }

        if ( 
'rp' === $tag_name or 'rt' === $tag_name ) {
            
// Close <rp> and <rt> if closing tag is omitted.
            
$this->end_tag'rp' );
            
$this->end_tag'rt' );
        }

        if ( 
'td' === $tag_name or 'th' === $tag_name ) {
            
// Close <td> and <th> if closing tag is omitted.
            
$this->end_tag'td' );
            
$this->end_tag'th' );
        }

        if ( 
'tr' === $tag_name ) {
            
// Close <tr> if closing tag is omitted.
            
$this->end_tag'tr' );
        }

        if ( 
'tbody' === $tag_name or 'tfoot' === $tag_name ) {
            
// Close <thead> if closing tag is omitted.
            
$this->end_tag'thead' );
        }

        if ( 
'tfoot' === $tag_name ) {
            
// Close <tbody> if closing tag is omitted.
            
$this->end_tag'tbody' );
        }

        if ( ! 
in_array$tag_nameself::void_elements ) ) {
            
array_unshift$this->stacked_elements$tag_name );
        }

        if ( ! 
in_array$tag_nameself::p_child_elements ) ) {
            if ( 
'' !== $this->output ) {
                
$this->output rtrim$this->output ) . "\n";
            }

            if ( 
$this->options['auto_indent'] ) {
                
$this->output .= self::indentcount$this->stacked_elements ) - );
            }
        }

        
$this->output .= $tag;
    }


    
/**
     * Closes an element and its open descendants at a time.
     *
     * @param string $tag An end tag.
     */
    
public function end_tag$tag ) {
        if ( 
preg_match'/<\/(.+?)(?:\s|>)/'$tag$matches ) ) {
            
$tag_name strtolower$matches[1] );
        } else {
            
$tag_name strtolower$tag );
        }

        
$stacked_elements array_values$this->stacked_elements );

        
$tag_position array_search$tag_name$stacked_elements );

        if ( 
false === $tag_position ) {
            return;
        }

        
// Element groups that make up an indirect nesting structure.
        // Descendant can contain ancestors.
        
static $nesting_families = array(
            array(
                
'ancestors' => array( 'dl', ),
                
'descendants' => array( 'dd''dt', ),
            ),
            array(
                
'ancestors' => array( 'ol''ul''menu', ),
                
'descendants' => array( 'li', ),
            ),
            array(
                
'ancestors' => array( 'table', ),
                
'descendants' => array( 'td''th''tr''thead''tbody''tfoot', ),
            ),
        );

        foreach ( 
$nesting_families as $family ) {
            
$ancestors = (array) $family['ancestors'];
            
$descendants = (array) $family['descendants'];

            if ( 
in_array$tag_name$descendants ) ) {
                
$intersect array_intersect(
                    
$ancestors,
                    
array_slice$stacked_elements0$tag_position )
                );

                if ( 
$intersect ) { // Ancestor appears after descendant.
                    
return;
                }
            }
        }

        while ( 
$element array_shift$this->stacked_elements ) ) {
            
$this->append_end_tag$element );

            if ( 
$element === $tag_name ) {
                break;
            }
        }
    }


    
/**
     * Closes all open tags.
     */
    
public function close_all_tags() {
        while ( 
$element array_shift$this->stacked_elements ) ) {
            
$this->append_end_tag$element );
        }
    }


    
/**
     * Appends an end tag to the output property.
     *
     * @param string $tag_name Tag name.
     */
    
public function append_end_tag$tag_name ) {
        if ( ! 
in_array$tag_nameself::p_child_elements ) ) {
            
// Remove unnecessary <br />.
            
$this->output preg_replace'/\s*<br \/>\s*$/'''$this->output );

            
$this->output rtrim$this->output ) . "\n";

            if ( 
$this->options['auto_indent'] ) {
                
$this->output .= self::indentcount$this->stacked_elements ) );
            }
        }

        
$this->output .= sprintf'</%s>'$tag_name );

        
// Remove trailing <p></p>.
        
$this->output preg_replace'/<p>\s*<\/p>$/'''$this->output );
    }


    
/**
     * Appends an HTML comment to the output property.
     *
     * @param string $tag An HTML comment.
     */
    
public function append_comment$tag ) {
        
$this->output .= $tag;
    }


    
/**
     * Returns true if it is currently inside one of HTML elements specified
     * by tag names.
     *
     * @param string|array $tag_names A tag name or an array of tag names.
     */
    
public function is_inside$tag_names ) {
        
$tag_names = (array) $tag_names;

        foreach ( 
$this->stacked_elements as $element ) {
            if ( 
in_array$element$tag_names ) ) {
                return 
true;
            }
        }

        return 
false;
    }


    
/**
     * Returns true if the parent node is one of HTML elements specified
     * by tag names.
     *
     * @param string|array $tag_names A tag name or an array of tag names.
     */
    
public function has_parent$tag_names ) {
        
$tag_names = (array) $tag_names;

        
$parent reset$this->stacked_elements );

        if ( 
false === $parent ) {
            return 
false;
        }

        return 
in_array$parent$tag_names );
    }


    
/**
     * Calculates the position of the next chunk based on the position and
     * length of the current chunk.
     *
     * @param array $chunk An associative array of the current chunk.
     * @return int The position of the next chunk.
     */
    
public static function calc_next_position$chunk ) {
        return 
$chunk['position'] + strlen$chunk['content'] );
    }


    
/**
     * Outputs a set of tabs to indent.
     *
     * @param int $level Indentation level.
     * @return string A series of tabs.
     */
    
public static function indent$level ) {
        
$level = (int) $level;

        if ( 
$level ) {
            return 
str_repeat"\t"$level );
        }

        return 
'';
    }


    
/**
     * Normalizes a start tag.
     *
     * @param string $tag A start tag or a tag name.
     * @return array An array includes the normalized start tag and tag name.
     */
    
public static function normalize_start_tag$tag ) {
        if ( 
preg_match'/<(.+?)[\s\/>]/'$tag$matches ) ) {
            
$tag_name strtolower$matches[1] );
        } else {
            
$tag_name strtolower$tag );
            
$tag sprintf'<%s>'$tag_name );
        }

        if ( 
in_array$tag_nameself::void_elements ) ) {
            
// Normalize void element.
            
$tag preg_replace'/\s*\/?>/'' />'$tag );
        }

        return array( 
$tag$tag_name );
    }


    
/**
     * Normalizes a paragraph of text.
     *
     * @param string $paragraph A paragraph of text.
     * @param bool $auto_br Optional. If true, line breaks will be replaced
     *             by a br element.
     * @return string The normalized paragraph.
     */
    
public static function normalize_paragraph$paragraph$auto_br false ) {
        if ( 
$auto_br ) {
            
$paragraph preg_replace'/\s*\n\s*/'"<br />\n"$paragraph );
        }

        
$paragraph preg_replace'/[ ]+/'" "$paragraph );

        return 
$paragraph;
    }

}

All system for education purposes only. For more tools: Telegram @jackleet

Mr.X Private Shell

Logo
-
New File | New Folder
Command
SQL