@@ -505,6 +505,45 @@ public function get_outer_markup() {
505505 return $ outer_markup ;
506506 }
507507
508+ /**
509+ * Replaces the raw HTML of the currently-matched tag with new HTML.
510+ * This replaces the entire contents of the tag including the tag itself.
511+ *
512+ * @param string $new_html
513+ * @return bool|null Whether the contents were updated.
514+ */
515+ public function set_outer_markup ( $ new_html ) {
516+ if ( null === $ this ->get_tag () ) {
517+ return null ;
518+ }
519+
520+ $ this ->set_bookmark ( 'start ' );
521+ $ start_tag = $ this ->current_token ->node_name ;
522+
523+ if ( self ::is_void ( $ start_tag ) ) {
524+ $ this ->replace_using_bookmarks ( $ new_html , 'before ' , 'start ' , 'after ' , 'start ' );
525+ $ this ->release_bookmark ( 'start ' );
526+ return true ;
527+ }
528+
529+ $ found_tag = $ this ->step_until_tag_is_closed ();
530+ $ this ->set_bookmark ( 'end ' );
531+
532+ if ( $ found_tag ) {
533+ $ did_close = $ this ->get_tag () === $ start_tag && $ this ->is_tag_closer ();
534+ $ end_position = $ did_close ? 'after ' : 'before ' ;
535+ $ this ->replace_using_bookmarks ( $ new_html , 'before ' , 'start ' , $ end_position , 'end ' );
536+ } else {
537+ // If there's no closing tag then the outer markup continues to the end of the document.
538+ $ this ->replace_using_bookmark ( $ new_html , 'before ' , 'start ' );
539+ }
540+
541+ $ this ->seek ( 'start ' );
542+ $ this ->release_bookmark ( 'start ' );
543+ $ this ->release_bookmark ( 'end ' );
544+ return true ;
545+ }
546+
508547 /**
509548 * Steps through the HTML document and stop at the next tag, if any.
510549 *
@@ -863,17 +902,55 @@ private function step_until_tag_is_closed() {
863902 return $ found_tag ;
864903 }
865904
905+ /**
906+ * Replaces content in the HTML document from a bookmark to the end of the document.
907+ *
908+ * @since 6.4.0
909+ *
910+ * @param string $html New HTML to insert into document.
911+ * @param string $start_position "before" to clip before bookmark, "after" to clip after.
912+ * @param string $start_bookmark_name Bookmark name at which to start clipping.
913+ */
914+ private function replace_using_bookmark ( $ html , $ start_position , $ start_bookmark_name ) {
915+ $ start_bookmark = $ this ->bookmarks [ "_ {$ start_bookmark_name }" ];
916+ $ start_offset = 'before ' === $ start_position ? $ start_bookmark ->start : $ start_bookmark ->end + 1 ;
917+
918+ $ this ->lexical_updates [] = new WP_HTML_Text_Replacement ( $ start_offset , strlen ( $ this ->html ), $ html );
919+ $ this ->apply_attributes_updates ();
920+ }
921+
922+ /**
923+ * Replaces content in the HTML document from one bookmark to another.
924+ *
925+ * @since 6.4.0
926+ *
927+ * @param string $html New HTML to insert into document.
928+ * @param string $start_position "before" to clip before bookmark, "after" to clip after.
929+ * @param string $start_bookmark_name Bookmark name at which to start clipping.
930+ * @param string $end_position "before" to clip before bookmark, "after" to clip after.
931+ * @param string $end_bookmark_name Bookmark name at which to end clipping.
932+ */
933+ private function replace_using_bookmarks ( $ html , $ start_position , $ start_bookmark_name , $ end_position , $ end_bookmark_name ) {
934+ $ start_bookmark = $ this ->bookmarks [ "_ {$ start_bookmark_name }" ];
935+ $ end_bookmark = $ this ->bookmarks [ "_ {$ end_bookmark_name }" ];
936+ $ start_offset = 'before ' === $ start_position ? $ start_bookmark ->start : $ start_bookmark ->end + 1 ;
937+ $ end_offset = 'before ' === $ end_position ? $ end_bookmark ->start : $ end_bookmark ->end + 1 ;
938+
939+ $ this ->lexical_updates [] = new WP_HTML_Text_Replacement ( $ start_offset , $ end_offset , $ html );
940+ $ this ->apply_attributes_updates ();
941+ }
942+
866943 /**
867944 * Returns a substring of the input HTML document from a bookmark until the end.
868945 *
869946 * @since 6.4.0
870947 *
871- * @param string $start_position "before" to clip before bookmark, "after" to clip after.
872- * @param string $start Bookmark name at which to start clipping.
948+ * @param string $start_position "before" to clip before bookmark, "after" to clip after.
949+ * @param string $start_bookmark_name Bookmark name at which to start clipping.
873950 * @return string Clipped substring of input HTMl document.
874951 */
875- private function substr_bookmark ( $ start_position , $ start ) {
876- $ start_bookmark = $ this ->bookmarks [ "_ {$ start }" ];
952+ private function substr_bookmark ( $ start_position , $ start_bookmark_name ) {
953+ $ start_bookmark = $ this ->bookmarks [ "_ {$ start_bookmark_name }" ];
877954 $ start_offset = 'before ' === $ start_position ? $ start_bookmark ->start : $ start_bookmark ->end + 1 ;
878955
879956 return substr ( $ this ->html , $ start_offset );
@@ -884,15 +961,15 @@ private function substr_bookmark( $start_position, $start ) {
884961 *
885962 * @since 6.4.0
886963 *
887- * @param string $start_position "before" to clip before bookmark, "after" to clip after.
888- * @param string $start Bookmark name at which to start clipping.
889- * @param string $end_position "before" to clip before bookmark, "after" to clip after.
890- * @param string $end Bookmark name at which to end clipping.
964+ * @param string $start_position "before" to clip before bookmark, "after" to clip after.
965+ * @param string $start_bookmark_name Bookmark name at which to start clipping.
966+ * @param string $end_position "before" to clip before bookmark, "after" to clip after.
967+ * @param string $end_bookmark_name Bookmark name at which to end clipping.
891968 * @return string Clipped substring of input HTMl document.
892969 */
893- private function substr_bookmarks ( $ start_position , $ start , $ end_position , $ end ) {
894- $ start_bookmark = $ this ->bookmarks [ "_ {$ start }" ];
895- $ end_bookmark = $ this ->bookmarks [ "_ {$ end }" ];
970+ private function substr_bookmarks ( $ start_position , $ start_bookmark_name , $ end_position , $ end_bookmark_name ) {
971+ $ start_bookmark = $ this ->bookmarks [ "_ {$ start_bookmark_name }" ];
972+ $ end_bookmark = $ this ->bookmarks [ "_ {$ end_bookmark_name }" ];
896973 $ start_offset = 'before ' === $ start_position ? $ start_bookmark ->start : $ start_bookmark ->end + 1 ;
897974 $ end_offset = 'before ' === $ end_position ? $ end_bookmark ->start : $ end_bookmark ->end + 1 ;
898975
0 commit comments