@@ -2359,13 +2359,14 @@ private function class_name_updates_to_attributes_updates(): void {
23592359 }
23602360
23612361 if ( false === $ existing_class && isset ( $ this ->attributes ['class ' ] ) ) {
2362- $ existing_class = WP_HTML_Decoder::decode_attribute (
2363- substr (
2364- $ this ->html ,
2365- $ this ->attributes ['class ' ]->value_starts_at ,
2366- $ this ->attributes ['class ' ]->value_length
2367- )
2362+ $ existing_class = substr (
2363+ $ this ->html ,
2364+ $ this ->attributes ['class ' ]->value_starts_at ,
2365+ $ this ->attributes ['class ' ]->value_length
23682366 );
2367+ $ existing_class = str_replace ( "\r\n" , "\n" , $ existing_class );
2368+ $ existing_class = str_replace ( "\r" , "\n" , $ existing_class );
2369+ $ existing_class = WP_HTML_Decoder::decode_attribute ( $ existing_class );
23692370 }
23702371
23712372 if ( false === $ existing_class ) {
@@ -2829,6 +2830,51 @@ public function get_attribute( $name ) {
28292830 return WP_HTML_Decoder::decode_attribute ( $ raw_value );
28302831 }
28312832
2833+ /**
2834+ * Returns the value of an attribute, applying HTML input stream preprocessing.
2835+ *
2836+ * This is intended for serialization, where source HTML values have already
2837+ * passed through preprocessing before character references decode. Enqueued
2838+ * attribute updates are plaintext API values, so they are returned unchanged.
2839+ *
2840+ * @since 6.9.0
2841+ * @ignore
2842+ *
2843+ * @param string $name Name of attribute whose value is requested.
2844+ * @return string|true|null Value of attribute or `null` if not available. Boolean attributes return `true`.
2845+ */
2846+ protected function get_attribute_for_serialization ( $ name ) {
2847+ if ( self ::STATE_MATCHED_TAG !== $ this ->parser_state ) {
2848+ return null ;
2849+ }
2850+
2851+ $ comparable = strtolower ( $ name );
2852+
2853+ if ( 'class ' === $ comparable ) {
2854+ $ this ->class_name_updates_to_attributes_updates ();
2855+ }
2856+
2857+ $ enqueued_value = $ this ->get_enqueued_attribute_value ( $ comparable );
2858+ if ( false !== $ enqueued_value ) {
2859+ return $ enqueued_value ;
2860+ }
2861+
2862+ if ( ! isset ( $ this ->attributes [ $ comparable ] ) ) {
2863+ return null ;
2864+ }
2865+
2866+ $ attribute = $ this ->attributes [ $ comparable ];
2867+ if ( true === $ attribute ->is_true ) {
2868+ return true ;
2869+ }
2870+
2871+ $ raw_value = substr ( $ this ->html , $ attribute ->value_starts_at , $ attribute ->value_length );
2872+ $ raw_value = str_replace ( "\r\n" , "\n" , $ raw_value );
2873+ $ raw_value = str_replace ( "\r" , "\n" , $ raw_value );
2874+
2875+ return WP_HTML_Decoder::decode_attribute ( $ raw_value );
2876+ }
2877+
28322878 /**
28332879 * Gets lowercase names of all attributes matching a given prefix in the current tag.
28342880 *
0 commit comments