[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/html-api/ -> class-wp-html-active-formatting-elements.php (source)

   1  <?php
   2  /**
   3   * HTML API: WP_HTML_Active_Formatting_Elements class
   4   *
   5   * @package WordPress
   6   * @subpackage HTML-API
   7   * @since 6.4.0
   8   */
   9  
  10  /**
  11   * Core class used by the HTML processor during HTML parsing
  12   * for managing the stack of active formatting elements.
  13   *
  14   * This class is designed for internal use by the HTML processor.
  15   *
  16   * > Initially, the list of active formatting elements is empty.
  17   * > It is used to handle mis-nested formatting element tags.
  18   * >
  19   * > The list contains elements in the formatting category, and markers.
  20   * > The markers are inserted when entering applet, object, marquee,
  21   * > template, td, th, and caption elements, and are used to prevent
  22   * > formatting from "leaking" into applet, object, marquee, template,
  23   * > td, th, and caption elements.
  24   * >
  25   * > In addition, each element in the list of active formatting elements
  26   * > is associated with the token for which it was created, so that
  27   * > further elements can be created for that token if necessary.
  28   *
  29   * @since 6.4.0
  30   *
  31   * @access private
  32   * @ignore
  33   *
  34   * @see https://html.spec.whatwg.org/#list-of-active-formatting-elements
  35   * @see WP_HTML_Processor
  36   */
  37  class WP_HTML_Active_Formatting_Elements {
  38      /**
  39       * Holds the stack of active formatting element references.
  40       *
  41       * @since 6.4.0
  42       *
  43       * @var WP_HTML_Token[]
  44       */
  45      private $stack = array();
  46  
  47      /**
  48       * Reports if a specific node is in the stack of active formatting elements.
  49       *
  50       * @since 6.4.0
  51       *
  52       * @param WP_HTML_Token $token Look for this node in the stack.
  53       * @return bool Whether the referenced node is in the stack of active formatting elements.
  54       */
  55  	public function contains_node( WP_HTML_Token $token ) {
  56          foreach ( $this->walk_up() as $item ) {
  57              if ( $token->bookmark_name === $item->bookmark_name ) {
  58                  return true;
  59              }
  60          }
  61  
  62          return false;
  63      }
  64  
  65      /**
  66       * Returns how many nodes are currently in the stack of active formatting elements.
  67       *
  68       * @since 6.4.0
  69       *
  70       * @return int How many nodes are in the stack of active formatting elements.
  71       */
  72  	public function count() {
  73          return count( $this->stack );
  74      }
  75  
  76      /**
  77       * Returns the node at the end of the stack of active formatting elements,
  78       * if one exists. If the stack is empty, returns null.
  79       *
  80       * @since 6.4.0
  81       *
  82       * @return WP_HTML_Token|null Last node in the stack of active formatting elements, if one exists, otherwise null.
  83       */
  84  	public function current_node() {
  85          $current_node = end( $this->stack );
  86  
  87          return $current_node ? $current_node : null;
  88      }
  89  
  90      /**
  91       * Inserts a "marker" at the end of the list of active formatting elements.
  92       *
  93       * > The markers are inserted when entering applet, object, marquee,
  94       * > template, td, th, and caption elements, and are used to prevent
  95       * > formatting from "leaking" into applet, object, marquee, template,
  96       * > td, th, and caption elements.
  97       *
  98       * @see https://html.spec.whatwg.org/#concept-parser-marker
  99       *
 100       * @since 6.7.0
 101       */
 102  	public function insert_marker(): void {
 103          $this->push( new WP_HTML_Token( null, 'marker', false ) );
 104      }
 105  
 106      /**
 107       * Pushes a node onto the stack of active formatting elements.
 108       *
 109       * @since 6.4.0
 110       *
 111       * @see https://html.spec.whatwg.org/#push-onto-the-list-of-active-formatting-elements
 112       *
 113       * @param WP_HTML_Token $token Push this node onto the stack.
 114       */
 115  	public function push( WP_HTML_Token $token ) {
 116          /*
 117           * > If there are already three elements in the list of active formatting elements after the last marker,
 118           * > if any, or anywhere in the list if there are no markers, that have the same tag name, namespace, and
 119           * > attributes as element, then remove the earliest such element from the list of active formatting
 120           * > elements. For these purposes, the attributes must be compared as they were when the elements were
 121           * > created by the parser; two elements have the same attributes if all their parsed attributes can be
 122           * > paired such that the two attributes in each pair have identical names, namespaces, and values
 123           * > (the order of the attributes does not matter).
 124           *
 125           * @todo Implement the "Noah's Ark clause" to only add up to three of any given kind of formatting elements to the stack.
 126           */
 127          // > Add element to the list of active formatting elements.
 128          $this->stack[] = $token;
 129      }
 130  
 131      /**
 132       * Removes a node from the stack of active formatting elements.
 133       *
 134       * @since 6.4.0
 135       *
 136       * @param WP_HTML_Token $token Remove this node from the stack, if it's there already.
 137       * @return bool Whether the node was found and removed from the stack of active formatting elements.
 138       */
 139  	public function remove_node( WP_HTML_Token $token ) {
 140          foreach ( $this->walk_up() as $position_from_end => $item ) {
 141              if ( $token->bookmark_name !== $item->bookmark_name ) {
 142                  continue;
 143              }
 144  
 145              $position_from_start = $this->count() - $position_from_end - 1;
 146              array_splice( $this->stack, $position_from_start, 1 );
 147              return true;
 148          }
 149  
 150          return false;
 151      }
 152  
 153      /**
 154       * Steps through the stack of active formatting elements, starting with the
 155       * top element (added first) and walking downwards to the one added last.
 156       *
 157       * This generator function is designed to be used inside a "foreach" loop.
 158       *
 159       * Example:
 160       *
 161       *     $html = '<em><strong><a>We are here';
 162       *     foreach ( $stack->walk_down() as $node ) {
 163       *         echo "{$node->node_name} -> ";
 164       *     }
 165       *     > EM -> STRONG -> A ->
 166       *
 167       * To start with the most-recently added element and walk towards the top,
 168       * see WP_HTML_Active_Formatting_Elements::walk_up().
 169       *
 170       * @since 6.4.0
 171       */
 172  	public function walk_down() {
 173          $count = count( $this->stack );
 174  
 175          for ( $i = 0; $i < $count; $i++ ) {
 176              yield $this->stack[ $i ];
 177          }
 178      }
 179  
 180      /**
 181       * Steps through the stack of active formatting elements, starting with the
 182       * bottom element (added last) and walking upwards to the one added first.
 183       *
 184       * This generator function is designed to be used inside a "foreach" loop.
 185       *
 186       * Example:
 187       *
 188       *     $html = '<em><strong><a>We are here';
 189       *     foreach ( $stack->walk_up() as $node ) {
 190       *         echo "{$node->node_name} -> ";
 191       *     }
 192       *     > A -> STRONG -> EM ->
 193       *
 194       * To start with the first added element and walk towards the bottom,
 195       * see WP_HTML_Active_Formatting_Elements::walk_down().
 196       *
 197       * @since 6.4.0
 198       */
 199  	public function walk_up() {
 200          for ( $i = count( $this->stack ) - 1; $i >= 0; $i-- ) {
 201              yield $this->stack[ $i ];
 202          }
 203      }
 204  
 205      /**
 206       * Clears the list of active formatting elements up to the last marker.
 207       *
 208       * > When the steps below require the UA to clear the list of active formatting elements up to
 209       * > the last marker, the UA must perform the following steps:
 210       * >
 211       * > 1. Let entry be the last (most recently added) entry in the list of active
 212       * >    formatting elements.
 213       * > 2. Remove entry from the list of active formatting elements.
 214       * > 3. If entry was a marker, then stop the algorithm at this point.
 215       * >    The list has been cleared up to the last marker.
 216       * > 4. Go to step 1.
 217       *
 218       * @see https://html.spec.whatwg.org/multipage/parsing.html#clear-the-list-of-active-formatting-elements-up-to-the-last-marker
 219       *
 220       * @since 6.7.0
 221       */
 222  	public function clear_up_to_last_marker(): void {
 223          foreach ( $this->walk_up() as $item ) {
 224              array_pop( $this->stack );
 225              if ( 'marker' === $item->node_name ) {
 226                  break;
 227              }
 228          }
 229      }
 230  }


Generated : Sat Jun 27 08:20:12 2026 Cross-referenced by PHPXref