'header_actions', 'aieo/trust-badges' => 'trust_badges', 'aieo/social-icons' => 'social', 'aieo/sso-buttons-block' => 'social_login', 'aieo/google-reviews' => 'google_reviews', 'aieo/business-info' => 'google_reviews', 'aieo/opening-hours' => 'google_reviews', 'aieo/store-info' => 'store_pages', 'aieo/store-locator' => 'store_pages', 'aieo/store-hero' => 'store_pages', 'aieo/store-map' => 'store_pages', 'aieo/data-table' => 'data_tables', 'aieo/my-contributions' => 'contributors', 'aieo/newsletter-signup' => 'newsletter_signup', 'aieo/category-hero' => 'category_extras', 'aieo/category-chips' => 'category_extras', 'aieo/category-lead' => 'category_extras', 'aieo/category-footer-hero' => 'category_extras', 'aieo/page-hero' => 'category_extras', 'aieo/blog-hero' => 'category_extras', 'aieo/blog-subcategories' => 'category_extras', 'aieo/latest-posts-overlay' => 'category_extras', 'aieo/taxonomy-archive-hero' => 'category_extras', 'aieo/taxonomy-archive-footer' => 'category_extras', 'aieo/taxonomy-related-articles' => 'category_extras', 'aieo/post-related-categories' => 'category_extras', 'aieo/post-related-brands' => 'brand_extras', 'aieo/brand-archive-hero' => 'brand_extras', 'aieo/brand-azindex' => 'brand_extras', 'aieo/brand-rails' => 'brand_extras', 'aieo/brand-related' => 'brand_extras', 'aieo/brand-slider' => 'brand_extras', 'aieo/brand-story' => 'brand_extras', 'aieo/post-related-needs' => 'need_extras', 'aieo/promo-surface' => 'promo_surfaces', 'aieo/semantic-related' => 'semantic', 'aieo/semantic-graph' => 'semantic', 'aieo/contact-form' => 'contact_form', 'aieo/loyalty-connection' => 'loyalty_classes', 'aieo/professional-signup' => 'role_pricing', 'aieo/sale-eligibility-message' => 'role_pricing', 'aieo/popup-panel' => 'popups', 'aieo/competition' => 'competitions', 'aieo/competition-status' => 'competitions', 'aieo/breadcrumb' => 'seo_general', 'aieo/custom-slot' => 'custom_slots', 'aieo/custom-slots-region' => 'custom_slots', 'aieo/event-registration' => 'events', 'aieo/free-shipping-pdp' => 'free_shipping_display', 'aieo/lowest-price-message' => 'price_history', 'aieo/post-meta' => 'product_meta', 'aieo/product-card-swatches' => 'swatches', 'aieo/product-needs' => 'product_needs_display', 'aieo/product-request' => 'product_requests_display', 'aieo/quote-basket' => 'product_requests_display', 'aieo/product-slider' => 'recommendations', 'aieo/recos' => 'recommendations', 'aieo/product-variations-gallery' => 'variations_gallery', 'aieo/menu' => 'menu', ); const VOID = array( 'AREA', 'BASE', 'BR', 'COL', 'EMBED', 'HR', 'IMG', 'INPUT', 'KEYGEN', 'LINK', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR' ); const RAW = array( 'SCRIPT', 'STYLE', 'TEXTAREA', 'TITLE', 'IFRAME', 'NOEMBED', 'NOFRAMES', 'XMP', 'PLAINTEXT' ); const SKIP = array( 'SCRIPT', 'STYLE', 'LINK', 'META', 'NOSCRIPT', 'TEMPLATE', 'BR' ); public static function boot() { static $done = false; if ( $done || is_admin() ) { return; } $done = true; add_filter( 'render_block', array( __CLASS__, 'mark_block' ), 20, 2 ); } public static function mark_block( $html, $block ) { $name = (string) ( $block['blockName'] ?? '' ); if ( 0 !== strpos( $name, 'aieo/' ) || '' === (string) $html ) { return $html; } if ( 'aieo/dmm-bridge' === $name ) { $module = sanitize_key( (string) ( $block['attrs']['moduleId'] ?? '' ) ); } else { $module = self::BLOCKS[ $name ] ?? str_replace( '-', '_', substr( $name, 5 ) ); } return '' === $module ? $html : self::mark( (string) $html, 'rooster-one/' . $module ); } public static function mark( $html, $id ) { $html = (string) $html; if ( false === strpos( $html, '<' ) ) { return $html; } $tags = new WP_HTML_Tag_Processor( $html ); $open = array(); $marked = false; while ( $tags->next_tag( array( 'tag_closers' => 'visit' ) ) ) { $tag = (string) $tags->get_tag(); if ( $tags->is_tag_closer() ) { $at = array_search( $tag, array_reverse( $open, true ), true ); if ( false !== $at ) { $open = array_slice( $open, 0, (int) $at ); } continue; } if ( ! $open && ! in_array( $tag, self::SKIP, true ) && null === $tags->get_attribute( 'data-rooster-ui' ) ) { $tags->set_attribute( 'data-rooster-ui', $id ); $marked = true; } if ( ! in_array( $tag, self::VOID, true ) && ! in_array( $tag, self::RAW, true ) && ! $tags->has_self_closing_flag() ) { $open[] = $tag; } } return $marked ? $tags->get_updated_html() : $html; } public static function attr( $module ) { return ' data-rooster-ui="' . esc_attr( 'rooster-one/' . $module ) . '"'; } } }