@@ -540,25 +540,32 @@ public static function data_script_tag_text_updates(): array {
540540 );
541541 }
542542
543-
544543 /**
545544 * @ticket TBD
546545 */
547- public function test_javascript_and_json_escaping () {
546+ public function test_complex_javascript_and_json_auto_escaping () {
548547 $ processor = new WP_HTML_Tag_Processor ( "<script></script> \n<script></script> \n<h1>OK</h1> " );
549548 $ processor ->next_tag ( 'SCRIPT ' );
550549 $ processor ->set_attribute ( 'type ' , 'importmap ' );
551- $ importmap = array (
550+ $ importmap_data = array (
552551 'imports ' => array (
553552 '</SCRIPT> \\<!-- \\<script> ' => "./script " ,
554553 ),
555554 );
555+
556556 $ importmap = json_encode (
557- $ importmap ,
557+ $ importmap_data ,
558558 JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS
559559 );
560560
561561 $ processor ->set_modifiable_text ( $ importmap );
562+ $ decoded_importmap = json_decode ( $ processor ->get_modifiable_text (), true , 512 , JSON_THROW_ON_ERROR );
563+ $ this ->assertEquals (
564+ $ importmap_data ,
565+ $ decoded_importmap ,
566+ 'Precondition failed: importmap JSON did not decode/encode as expected: ' . json_last_error_msg ()
567+ );
568+
562569 $ processor ->next_tag ( 'SCRIPT ' );
563570 $ processor ->set_attribute ( 'type ' , 'module ' );
564571 $ javascript = <<<'JS'
@@ -571,6 +578,56 @@ public function test_javascript_and_json_escaping() {
571578<script type="module">import '</\u0053CRIPT>\\<!--\\<\u0073cript>';</script>
572579<h1>OK</h1>
573580HTML;
574- $ this ->assertEqualHTML ( $ expected , $ processor ->get_updated_html () );
581+ $ updated_html = $ processor ->get_updated_html ();
582+ $ this ->assertEqualHTML ( $ expected , $ updated_html );
583+
584+ // Re-process and verify the JSON is correct.
585+ $ processor = new WP_HTML_Tag_Processor ( $ updated_html );
586+ $ processor ->next_tag ( 'SCRIPT ' );
587+ $ this ->assertSame ( 'importmap ' , $ processor ->get_attribute ( 'type ' ) );
588+ $ importmap_json = $ processor ->get_modifiable_text ();
589+ $ decoded_importmap = json_decode ( $ importmap_json , true );
590+ $ this ->assertSame ( 'No error ' , json_last_error_msg () );
591+ $ this ->assertEquals (
592+ $ importmap_data ,
593+ $ decoded_importmap ,
594+ 'Precondition failed: re-processed importmap JSON did not decode/encode as expected: ' . json_last_error_msg ()
595+ );
596+ }
597+
598+ /**
599+ * @ticket TBD
600+ */
601+ public function test_json_auto_escaping () {
602+ // This is not a typical JSON encoding or escaping, but it is valid.
603+ $ json_text = '"Escaped BS: \\\\; Escaped BS+LT: \\\\<; Unescaped LT: <; Script closer: </script>" ' ;
604+ $ expected_decoded_json = 'Escaped BS: \\; Escaped BS+LT: \\<; Unescaped LT: <; Script closer: </script> ' ;
605+ $ decoded_json = json_decode ( $ json_text , false , 512 , JSON_THROW_ON_ERROR );
606+ $ this ->assertSame (
607+ $ expected_decoded_json ,
608+ $ decoded_json ,
609+ 'Precondition failed: test JSON text did not decode as expected. '
610+ );
611+
612+ $ processor = new WP_HTML_Tag_Processor ( '<script type="application/json"></script> ' );
613+ $ processor ->next_tag ( 'SCRIPT ' );
614+
615+ $ processor ->set_modifiable_text ( $ json_text );
616+
617+ $ expected = <<<'HTML'
618+ <script type="application/json">"Escaped BS: \\; Escaped BS+LT: \\\u003C; Unescaped LT: \u003C; Script closer: \u003C/script>"</script>
619+ HTML;
620+
621+ $ updated_html = $ processor ->get_updated_html ();
622+ $ this ->assertEqualHTML ( $ expected , $ updated_html );
623+
624+ // Reprocess to ensure JSON value survives HTML round trip:
625+ $ processor = new WP_HTML_Tag_Processor ( $ expected );
626+ $ processor ->next_tag ( 'SCRIPT ' );
627+ $ decoded_json_from_html = json_decode ( $ processor ->get_modifiable_text (), true , 512 , JSON_THROW_ON_ERROR );
628+ $ this ->assertEquals (
629+ $ expected_decoded_json ,
630+ $ decoded_json_from_html ,
631+ );
575632 }
576633}
0 commit comments