WP_HTML_Tag_Processor::apply_attributes_updates( int $shift_this_point ): int

In this article

This function’s access is marked private. This means it is not intended for use by plugin or theme developers, only in other core functions. It is listed here for completeness.

Applies attribute updates to HTML document.

Parameters

$shift_this_pointintrequired
Accumulate and return shift for this position.

Return

int How many bytes the given pointer moved in response to the updates.

Source

private function apply_attributes_updates( $shift_this_point = 0 ) {
	if ( ! count( $this->lexical_updates ) ) {
		return 0;
	}

	$accumulated_shift_for_given_point = 0;

	/*
	 * Attribute updates can be enqueued in any order but updates
	 * to the document must occur in lexical order; that is, each
	 * replacement must be made before all others which follow it
	 * at later string indices in the input document.
	 *
	 * Sorting avoid making out-of-order replacements which
	 * can lead to mangled output, partially-duplicated
	 * attributes, and overwritten attributes.
	 */
	usort( $this->lexical_updates, array( self::class, 'sort_start_ascending' ) );

	$bytes_already_copied = 0;
	$output_buffer        = '';
	foreach ( $this->lexical_updates as $diff ) {
		$shift = strlen( $diff->text ) - ( $diff->end - $diff->start );

		// Adjust the cursor position by however much an update affects it.
		if ( $diff->start <= $this->bytes_already_parsed ) {
			$this->bytes_already_parsed += $shift;
		}

		// Accumulate shift of the given pointer within this function call.
		if ( $diff->start <= $shift_this_point ) {
			$accumulated_shift_for_given_point += $shift;
		}

		$output_buffer       .= substr( $this->html, $bytes_already_copied, $diff->start - $bytes_already_copied );
		$output_buffer       .= $diff->text;
		$bytes_already_copied = $diff->end;
	}

	$this->html = $output_buffer . substr( $this->html, $bytes_already_copied );

	/*
	 * Adjust bookmark locations to account for how the text
	 * replacements adjust offsets in the input document.
	 */
	foreach ( $this->bookmarks as $bookmark_name => $bookmark ) {
		/*
		 * Each lexical update which appears before the bookmark's endpoints
		 * might shift the offsets for those endpoints. Loop through each change
		 * and accumulate the total shift for each bookmark, then apply that
		 * shift after tallying the full delta.
		 */
		$head_delta = 0;
		$tail_delta = 0;

		foreach ( $this->lexical_updates as $diff ) {
			if ( $bookmark->start < $diff->start && $bookmark->end < $diff->start ) {
				break;
			}

			if ( $bookmark->start >= $diff->start && $bookmark->end < $diff->end ) {
				$this->release_bookmark( $bookmark_name );
				continue 2;
			}

			$delta = strlen( $diff->text ) - ( $diff->end - $diff->start );

			if ( $bookmark->start >= $diff->start ) {
				$head_delta += $delta;
			}

			if ( $bookmark->end >= $diff->end ) {
				$tail_delta += $delta;
			}
		}

		$bookmark->start += $head_delta;
		$bookmark->end   += $tail_delta;
	}

	$this->lexical_updates = array();

	return $accumulated_shift_for_given_point;
}

Changelog

VersionDescription
6.3.0Invalidate any bookmarks whose targets are overwritten.
6.2.1Accumulates shift for internal cursor and passed pointer.
6.2.0Introduced.

User Contributed Notes

You must log in before being able to contribute a note or feedback.