- Timestamp:
- 05/03/2023 12:09:22 PM (18 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/6.2/src/wp-includes/html-api/class-wp-html-tag-processor.php
r55707 r55708 319 319 320 320 /** 321 * Holds updated HTML as updates are applied.322 *323 * Updates and unmodified portions of the input document are324 * appended to this value as they are applied. It will hold325 * a copy of the updated document up until the point of the326 * latest applied update. The fully-updated HTML document327 * will comprise this value plus the part of the input document328 * which follows that latest update.329 *330 * @see $bytes_already_copied331 *332 * @since 6.2.0333 * @var string334 */335 private $output_buffer = '';336 337 /**338 321 * How many bytes from the original HTML document have been read and parsed. 339 322 * … … 346 329 */ 347 330 private $bytes_already_parsed = 0; 348 349 /**350 * How many bytes from the input HTML document have already been351 * copied into the output buffer.352 *353 * Lexical updates are enqueued and processed in batches. Prior354 * to any given update in the input document, there might exist355 * a span of HTML unaffected by any changes. This span ought to356 * be copied verbatim into the output buffer before applying the357 * following update. This value will point to the starting byte358 * offset in the input document where that unaffected span of359 * HTML starts.360 *361 * @since 6.2.0362 * @var int363 */364 private $bytes_already_copied = 0;365 331 366 332 /** … … 1304 1270 */ 1305 1271 private function after_tag() { 1306 $this->class_name_updates_to_attributes_updates(); 1307 $this->apply_attributes_updates(); 1272 $this->get_updated_html(); 1308 1273 $this->tag_name_starts_at = null; 1309 1274 $this->tag_name_length = null; … … 1461 1426 * 1462 1427 * @since 6.2.0 1463 * 1464 * @return void 1465 */ 1466 private function apply_attributes_updates() { 1428 * @since 6.2.1 Accumulates shift for internal cursor and passed pointer. 1429 * 1430 * @param int $shift_this_point Accumulate and return shift for this position. 1431 * @return int How many bytes the given pointer moved in response to the updates. 1432 */ 1433 private function apply_attributes_updates( $shift_this_point = 0 ) { 1467 1434 if ( ! count( $this->lexical_updates ) ) { 1468 return; 1469 } 1435 return 0; 1436 } 1437 1438 $accumulated_shift_for_given_point = 0; 1470 1439 1471 1440 /* … … 1481 1450 usort( $this->lexical_updates, array( self::class, 'sort_start_ascending' ) ); 1482 1451 1452 $bytes_already_copied = 0; 1453 $output_buffer = ''; 1483 1454 foreach ( $this->lexical_updates as $diff ) { 1484 $this->output_buffer .= substr( $this->html, $this->bytes_already_copied, $diff->start - $this->bytes_already_copied ); 1485 $this->output_buffer .= $diff->text; 1486 $this->bytes_already_copied = $diff->end; 1487 } 1455 $shift = strlen( $diff->text ) - ( $diff->end - $diff->start ); 1456 1457 // Adjust the cursor position by however much an update affects it. 1458 if ( $diff->start <= $this->bytes_already_parsed ) { 1459 $this->bytes_already_parsed += $shift; 1460 } 1461 1462 // Accumulate shift of the given pointer within this function call. 1463 if ( $diff->start <= $shift_this_point ) { 1464 $accumulated_shift_for_given_point += $shift; 1465 } 1466 1467 $output_buffer .= substr( $this->html, $bytes_already_copied, $diff->start - $bytes_already_copied ); 1468 $output_buffer .= $diff->text; 1469 $bytes_already_copied = $diff->end; 1470 } 1471 1472 $this->html = $output_buffer . substr( $this->html, $bytes_already_copied ); 1488 1473 1489 1474 /* … … 1525 1510 1526 1511 $this->lexical_updates = array(); 1512 1513 return $accumulated_shift_for_given_point; 1527 1514 } 1528 1515 … … 1562 1549 // Point this tag processor before the sought tag opener and consume it. 1563 1550 $this->bytes_already_parsed = $this->bookmarks[ $bookmark_name ]->start; 1564 $this->bytes_already_copied = $this->bytes_already_parsed;1565 $this->output_buffer = substr( $this->html, 0, $this->bytes_already_copied );1566 1551 return $this->next_tag( array( 'tag_closers' => 'visit' ) ); 1567 1552 } … … 2083 2068 * 2084 2069 * @since 6.2.0 2070 * @since 6.2.1 Shifts the internal cursor corresponding to the applied updates. 2085 2071 * 2086 2072 * @return string The processed HTML. … … 2093 2079 * updated, return the original document and avoid a string copy. 2094 2080 */ 2095 if ( $requires_no_updating && 0 === $this->bytes_already_copied) {2081 if ( $requires_no_updating ) { 2096 2082 return $this->html; 2097 2083 } 2098 2084 2099 2085 /* 2100 * If there are no updates left to apply, but some have already 2101 * been applied, then finish by copying the rest of the input 2102 * to the end of the updated document and return. 2103 */ 2104 if ( $requires_no_updating && $this->bytes_already_copied > 0 ) { 2105 $this->html = $this->output_buffer . substr( $this->html, $this->bytes_already_copied ); 2106 $this->bytes_already_copied = strlen( $this->output_buffer ); 2107 return $this->output_buffer . substr( $this->html, $this->bytes_already_copied ); 2108 } 2109 2110 // Apply the updates, rewind to before the current tag, and reparse the attributes. 2111 $content_up_to_opened_tag_name = $this->output_buffer . substr( 2112 $this->html, 2113 $this->bytes_already_copied, 2114 $this->tag_name_starts_at + $this->tag_name_length - $this->bytes_already_copied 2115 ); 2086 * Keep track of the position right before the current tag. This will 2087 * be necessary for reparsing the current tag after updating the HTML. 2088 */ 2089 $before_current_tag = $this->tag_name_starts_at - 1; 2116 2090 2117 2091 /* 2118 * 1. Apply the edits by flushing them to the output buffer and updating the copied byte count. 2119 * 2120 * Note: `apply_attributes_updates()` modifies `$this->output_buffer`. 2092 * 1. Apply the enqueued edits and update all the pointers to reflect those changes. 2121 2093 */ 2122 2094 $this->class_name_updates_to_attributes_updates(); 2123 $ this->apply_attributes_updates();2095 $before_current_tag += $this->apply_attributes_updates( $before_current_tag ); 2124 2096 2125 2097 /* 2126 * 2. Replace the original HTML with the now-updated HTML so that it's possible to 2127 * seek to a previous location and have a consistent view of the updated document. 2128 */ 2129 $this->html = $this->output_buffer . substr( $this->html, $this->bytes_already_copied ); 2130 $this->output_buffer = $content_up_to_opened_tag_name; 2131 $this->bytes_already_copied = strlen( $this->output_buffer ); 2132 2133 /* 2134 * 3. Point this tag processor at the original tag opener and consume it 2098 * 2. Rewind to before the current tag and reparse to get updated attributes. 2135 2099 * 2136 2100 * At this point the internal cursor points to the end of the tag name. … … 2144 2108 * \<-/ back up by strlen("em") + 1 ==> 3 2145 2109 */ 2146 $this->bytes_already_parsed = strlen( $content_up_to_opened_tag_name ) - $this->tag_name_length - 1; 2110 2111 // Store existing state so it can be restored after reparsing. 2112 $previous_parsed_byte_count = $this->bytes_already_parsed; 2113 $previous_query = $this->last_query; 2114 2115 // Reparse attributes. 2116 $this->bytes_already_parsed = $before_current_tag; 2147 2117 $this->next_tag(); 2118 2119 // Restore previous state. 2120 $this->bytes_already_parsed = $previous_parsed_byte_count; 2121 $this->parse_query( $previous_query ); 2148 2122 2149 2123 return $this->html;
Note: See TracChangeset
for help on using the changeset viewer.