Applies attribute updates to HTML document.
Parameters
$shift_this_pointintrequired- Accumulate and return shift for this position.
Source
*
* This flag is set upon the first change that requires a string update.
*
* @var bool $modified
*/
$modified = false;
$seen = array();
$to_remove = array();
$is_quirks = self::QUIRKS_MODE === $this->compat_mode;
if ( $is_quirks ) {
foreach ( $this->classname_updates as $updated_name => $action ) {
if ( self::REMOVE_CLASS === $action ) {
$to_remove[] = strtolower( $updated_name );
}
}
} else {
foreach ( $this->classname_updates as $updated_name => $action ) {
if ( self::REMOVE_CLASS === $action ) {
$to_remove[] = $updated_name;
}
}
}
// Remove unwanted classes by only copying the new ones.
$existing_class_length = strlen( $existing_class );
while ( $at < $existing_class_length ) {
// Skip to the first non-whitespace character.
$ws_at = $at;
$ws_length = strspn( $existing_class, " \t\f\r\n", $ws_at );
$at += $ws_length;
// Capture the class name – it's everything until the next whitespace.
$name_length = strcspn( $existing_class, " \t\f\r\n", $at );
if ( 0 === $name_length ) {
// If no more class names are found then that's the end.
break;
}
$name = substr( $existing_class, $at, $name_length );
$comparable_class_name = $is_quirks ? strtolower( $name ) : $name;
$at += $name_length;
// If this class is marked for removal, remove it and move on to the next one.
if ( in_array( $comparable_class_name, $to_remove, true ) ) {
$modified = true;
continue;
}
// If a class has already been seen then skip it; it should not be added twice.
if ( in_array( $comparable_class_name, $seen, true ) ) {
continue;
}
$seen[] = $comparable_class_name;
/*
* Otherwise, append it to the new "class" attribute value.
*
* There are options for handling whitespace between tags.
* Preserving the existing whitespace produces fewer changes
* to the HTML content and should clarify the before/after
* content when debugging the modified output.
*
* This approach contrasts normalizing the inter-class
* whitespace to a single space, which might appear cleaner
* in the output HTML but produce a noisier change.
*/
if ( '' !== $class ) {
$class .= substr( $existing_class, $ws_at, $ws_length );
}
$class .= $name;
}
// Add new classes by appending those which haven't already been seen.
foreach ( $this->classname_updates as $name => $operation ) {
$comparable_name = $is_quirks ? strtolower( $name ) : $name;
if ( self::ADD_CLASS === $operation && ! in_array( $comparable_name, $seen, true ) ) {
$modified = true;
$class .= strlen( $class ) > 0 ? ' ' : '';
$class .= $name;
}
}
$this->classname_updates = array();
if ( ! $modified ) {
return;
User Contributed Notes
You must log in before being able to contribute a note or feedback.