PluginProbe
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress / 9.1.4
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress v9.1.4
9.2.0 9.1.4 9.1.3 9.1.2 9.1.1 9.1.0 9.0.3 9.0.2 9.0.1 9.0.0 8.5.79 8.5.78 8.5.77 8.5.76 8.5.75 8.5.74 8.5.73 8.5.72 8.5.71 8.5.70 8.5.69 8.5.68 8.5.35 8.5.36 8.5.37 All 224 releases
← All changes | legacy/admin/classes/class-wpvr-scene.php +179 -91 9.1.2 → 9.1.4 View file →
@@ -1051,10 +1051,18 @@
1051 1051 ob_start();
1052 1052 do_action('wpvr_hotspot_content', $hotspot_data);
1053 1053 $hotspot_content = ob_get_clean();
1054 1054
1055 - if (!$hotspot_content) {
1056 - $hotspot_content = $hotspot_data["hotspot-content"];
1055 + $is_fluent_form = isset($hotspot_data["hotspot-type"]) && 'fluent_form' === $hotspot_data["hotspot-type"];
1056 +
1057 + if ($is_fluent_form) {
1058 + if (!empty($hotspot_content)) {
1059 + $hotspot_content = preg_replace('/<script\b[^>]*>[\s\S]*?<\/script>/i', '', $hotspot_content);
1060 + }
1061 + } else {
1062 + if (!$hotspot_content) {
1063 + $hotspot_content = $hotspot_data["hotspot-content"] ?? '';
1064 + }
1057 1065 }
1058 1066
1059 1067 $hotspot_url = $this->normalize_hotspot_external_url($hotspot_data["hotspot-url"] ?? '');
1060 1068
@@ -1074,9 +1082,8 @@
1074 1082 $hotspot_data['hotspot-hover'] ?? ''
1075 1083 );
1076 1084
1077 1085
1078 - $is_fluent_form = isset($hotspot_data["hotspot-type"]) && 'fluent_form' === $hotspot_data["hotspot-type"];
1079 1086 $on_hover_content = $this->sanitize_content_preserve_styles($on_hover_content ?? '', false);
1080 1087 $on_click_content = preg_replace_callback('/<img[^>]*>/', "replace_callback", $hotspot_content ?? '');
1081 1088 $on_click_content = $this->sanitize_content_preserve_styles($on_click_content ?? '', $is_fluent_form);
1082 1089
@@ -1515,20 +1522,24 @@
1515 1522 $animation_css = apply_filters('wpvr_tour_scene_animation',$animation_type,$animationDuration,$animationDelay,$postdata,$id);
1516 1523 $html .= $animation_css;
1517 1524 }
1518 1525
1526 + $container_width = $width;
1527 + $container_height = $height;
1528 + $container_mobile_height = $mobile_height;
1529 +
1519 1530 if ($width == 'fullwidth') {
1520 - $width = "100%";
1531 + $container_width = "100%";
1521 1532 } elseif ($width == 'embed') {
1522 - $width = "100%";
1523 - $height = "100%";
1524 - $mobile_height = "100%";
1533 + $container_width = "100%";
1534 + $container_height = "100%";
1535 + $container_mobile_height = "100%";
1525 1536 }
1526 1537
1527 1538 if (wpvr_isMobileDevice()) {
1528 - $html .= '<div id="' . $master_container_id . '" class="wpvr-master-container wpvr-cardboard '.$enable_cardboard.'" style="max-width:' . $width . '; width: 100%; height: ' . $mobile_height . '; border-radius:' . $radius . '; direction:ltr; ">';
1539 + $html .= '<div id="' . $master_container_id . '" class="wpvr-master-container wpvr-cardboard '.$enable_cardboard.'" style="max-width:' . $container_width . '; width: 100%; height: ' . $container_mobile_height . '; border-radius:' . $radius . '; direction:ltr; ">';
1529 1540 } else {
1530 - $html .= '<div id="' . $master_container_id . '" class="wpvr-master-container wpvr-cardboard '.$enable_cardboard.'" style="max-width:' . $width . '; width: 100%; height: ' . $height . '; border-radius:' . $radius . '; direction:ltr; ">';
1541 + $html .= '<div id="' . $master_container_id . '" class="wpvr-master-container wpvr-cardboard '.$enable_cardboard.'" style="max-width:' . $container_width . '; width: 100%; height: ' . $container_height . '; border-radius:' . $radius . '; direction:ltr; ">';
1531 1542 }
1532 1543 $is_pro = apply_filters('is_wpvr_pro_active',false);
1533 1544 $status = get_option('wpvr_edd_license_status');
1534 1545 $is_cardboard = get_option('wpvr_cardboard_disable');
@@ -1573,9 +1584,9 @@
1573 1584 }
1574 1585 } elseif ($width == 'embed') {
1575 1586 $html .= '<div class="cardboard-vrembed vrembed">';
1576 1587 $html .= '<div id="' . $panoid2 . '" class="pano-wrap pano-left pano2' . $id . '" style=" width: 49%!important; text-align:center; direction:ltr;" ><div id="center-pointer2' . $pano_suffix . '" class="vr-pointer-container"><span class="center-pointer"></span></div></div>';
1577 - $html .= '<div id="' . $panoid . '" class="pano-wrap pano-right pano' . $id . '" style=" text-align:center; direction:ltr;" >';
1588 + $html .= '<div id="' . $panoid . '" class="pano-wrap pano-right pano' . $id . '" style="width: 100%; height: 100%; text-align:center; direction:ltr;" >';
1578 1589 } else {
1579 1590 if (wpvr_isMobileDevice()) {
1580 1591 $html .= '<div id="' . $panoid2 . '" class="pano-wrap pano-left cardboard-half pano2' . $id . '" style="width: 49%; border-radius:' . $radius . '"><div id="center-pointer2' . $pano_suffix . '" class="vr-pointer-container"><span class="center-pointer"></span></div></div>';
1581 1592 if ($radius) {
@@ -1754,14 +1765,13 @@
1754 1765 //===explainer button end===//
1755 1766
1756 1767 //===Floor map button===//
1757 1768 $status = get_option('wpvr_edd_license_status');
1758 - if ($status !== false && 'valid' == $status && $is_pro){
1759 - if ($floor_plan_enable == "on" && !empty($floor_plan_image)) {
1760 - $html .= '<div class="floor_map_button" id="floor_map_button_' . $pano_suffix . '" style="right:'.$floor_map_right.'">';
1761 - $html .= '<div class="ctrl" id="floor_map_target_' . $pano_suffix . '"><i class="fas fa-map" style="color:#f7fffb;"></i></div>';
1762 - $html .= '</div>';
1763 - }
1769 + $has_floor_plan = ( $status !== false && 'valid' == $status && $is_pro && 'on' == $floor_plan_enable && ! empty( $floor_plan_image ) );
1770 + if ( $has_floor_plan ) {
1771 + $html .= '<div class="floor_map_button" id="floor_map_button_' . $pano_suffix . '" style="right:'.$floor_map_right.'">';
1772 + $html .= '<div class="ctrl" id="floor_map_target_' . $pano_suffix . '"><i class="fas fa-map" style="color:#f7fffb;"></i></div>';
1773 + $html .= '</div>';
1764 1774 }
1765 1775 //===floor map button===//
1766 1776
1767 1777 if ($vrgallery && 'valid' == $status && $is_pro ) {
@@ -1897,45 +1907,88 @@
1897 1907 </div>';
1898 1908 }
1899 1909 }
1900 1910 //===Floor plan section===//
1901 - $floor_map_image = "";
1902 - $floor_map_pointer = array();
1903 - $floor_map_scene_id = '';
1904 - $floor_plan_custom_color = '#cca92c';
1905 - $floor_plan_direction_indicator = isset($postdata['floor_plan_direction_indicator']) ? $postdata['floor_plan_direction_indicator'] : 'on';
1911 + if ( $has_floor_plan ) {
1912 + $floor_map_image = $floor_plan_image;
1913 + $floor_map_pointer = isset($postdata['floor_plan_pointer_position']) && is_array($postdata['floor_plan_pointer_position']) ? $postdata['floor_plan_pointer_position'] : array();
1914 + $floor_map_scene_id = isset($postdata['floor_plan_data_list']) && is_array($postdata['floor_plan_data_list']) ? $postdata['floor_plan_data_list'] : array();
1915 + $floor_plan_custom_color = isset($postdata['floor_plan_custom_color']) && ! empty($postdata['floor_plan_custom_color']) ? $postdata['floor_plan_custom_color'] : '#cca92c';
1916 + $floor_plan_direction_indicator = isset($postdata['floor_plan_direction_indicator']) ? $postdata['floor_plan_direction_indicator'] : 'on';
1906 1917
1907 - if (isset($postdata['floor_plan_attachment_url'])) {
1908 - $floor_map_image = $postdata['floor_plan_attachment_url'];
1909 - $floor_map_pointer = $postdata['floor_plan_pointer_position'];
1910 - $floor_map_scene_id = $postdata['floor_plan_data_list'];
1911 - $floor_plan_custom_color = $postdata['floor_plan_custom_color'];
1912 - }
1913 - $html .= '<div class="wpvr-floor-map" id="wpvr-floor-map' . $pano_suffix . '" style="display: none">';
1914 - $html .= '<span class="close-floor-map-plan"><i class="fa fa-times"></i></span>';
1915 - $html .= '<img loading="lazy" src="'.$floor_map_image.'">';
1916 - foreach($floor_map_pointer as $key=> $pointer_position){
1917 - $html .= '<div class="floor-plan-pointer ui-draggable ui-draggable-handle" scene_id = "'.$floor_map_scene_id[$key]->value.'" id="'.$pointer_position->id.'" data-top="'.$pointer_position->data_top.'" data-left="'.$pointer_position->data_left.'" style="'.$pointer_position->style.'">
1918 - <svg class="floor-pointer-circle" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
1919 - <circle cx="12" cy="12" r="11.5" stroke="'.$floor_plan_custom_color.'"/>
1920 - <circle cx="12" cy="12" r="5" fill="'.$foreground_color_pointer.'"/>
1921 - </svg>';
1922 -
1923 - // Only add the floor pointer flash SVG if floor_plan_direction_indicator is "on"
1924 - if ($floor_plan_direction_indicator === "on") {
1925 - $html .= '<svg class="floor-pointer-flash" width="54" height="35" viewBox="0 0 54 35" fill="none" xmlns="http://www.w3.org/2000/svg">
1926 - <path d="M0.454054 1.32433L11.7683 34.3243C11.9069 34.7285 12.287 35 12.7143 35H41.2857C41.713 35 42.0931 34.7285 42.2317 34.3243L53.5459 1.32432C53.7685 0.675257 53.2862 0 52.6 0H1.4C0.713843 0 0.231517 0.675258 0.454054 1.32433Z" fill="url(#paint0_linear_1_10)"/>
1927 - <defs>
1928 - <linearGradient id="paint0_linear_1_10" x1="27" y1="4.59807e-08" x2="26.5" y2="28" gradientUnits="userSpaceOnUse">
1929 - <stop stop-color="' . esc_attr( $floor_plan_custom_color ) . '" stop-opacity="0"/>
1930 - <stop offset="1" stop-color="' . esc_attr( $floor_plan_custom_color ) . '"/>
1931 - </linearGradient>
1932 - </defs>
1933 - </svg>';
1918 + $media_alt = '';
1919 + $attachment_id = attachment_url_to_postid( $floor_map_image );
1920 +
1921 + if ( $attachment_id ) {
1922 + $media_alt = sanitize_text_field( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) );
1923 + }
1924 +
1925 + if ( ! empty( $media_alt ) ) {
1926 + $floor_map_alt = $media_alt;
1927 + } else {
1928 + $tour_title = sanitize_text_field( get_the_title( $id ) );
1929 +
1930 + $floor_map_alt = ! empty( $tour_title )
1931 + /* translators: %s: tour title */
1932 + ? sprintf( __( '%s - Floor Plan', 'wpvr' ), $tour_title )
1933 + : __( 'Floor Plan', 'wpvr' );
1934 + }
1935 +
1936 + $html .= '<div class="wpvr-floor-map" id="wpvr-floor-map' . $pano_suffix . '" style="display: none">';
1937 + $html .= '<span class="close-floor-map-plan"><i class="fa fa-times"></i></span>';
1938 + $html .= '<img loading="lazy" src="' . esc_url( $floor_map_image ) . '" alt="' . esc_attr( $floor_map_alt ) . '">';
1939 + foreach ( $floor_map_pointer as $key => $pointer_position ) {
1940 + $pointer_id = '';
1941 + $data_top = '';
1942 + $data_left = '';
1943 + $style = '';
1944 +
1945 + if ( is_object( $pointer_position ) ) {
1946 + $pointer_id = isset( $pointer_position->id ) ? (string) $pointer_position->id : '';
1947 + $data_top = isset( $pointer_position->data_top ) ? (string) $pointer_position->data_top : '';
1948 + $data_left = isset( $pointer_position->data_left ) ? (string) $pointer_position->data_left : '';
1949 + $style = isset( $pointer_position->style ) ? (string) $pointer_position->style : '';
1950 + } elseif ( is_array( $pointer_position ) ) {
1951 + $pointer_id = isset( $pointer_position['id'] ) ? (string) $pointer_position['id'] : '';
1952 + $data_top = isset( $pointer_position['data_top'] ) ? (string) $pointer_position['data_top'] : '';
1953 + $data_left = isset( $pointer_position['data_left'] ) ? (string) $pointer_position['data_left'] : '';
1954 + $style = isset( $pointer_position['style'] ) ? (string) $pointer_position['style'] : '';
1955 + }
1956 +
1957 + $scene_id_val = '';
1958 + if ( isset( $floor_map_scene_id[ $key ] ) ) {
1959 + $scene_item = $floor_map_scene_id[ $key ];
1960 + if ( is_object( $scene_item ) && isset( $scene_item->value ) ) {
1961 + $scene_id_val = (string) $scene_item->value;
1962 + } elseif ( is_array( $scene_item ) && isset( $scene_item['value'] ) ) {
1963 + $scene_id_val = (string) $scene_item['value'];
1964 + } elseif ( is_scalar( $scene_item ) ) {
1965 + $scene_id_val = (string) $scene_item;
1934 1966 }
1967 + }
1968 +
1969 + $html .= '<div class="floor-plan-pointer ui-draggable ui-draggable-handle" scene_id="' . esc_attr( $scene_id_val ) . '" id="' . esc_attr( $pointer_id ) . '" data-top="' . esc_attr( $data_top ) . '" data-left="' . esc_attr( $data_left ) . '" style="' . esc_attr( $style ) . '">
1970 + <svg class="floor-pointer-circle" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
1971 + <circle cx="12" cy="12" r="11.5" stroke="' . esc_attr( $floor_plan_custom_color ) . '"/>
1972 + <circle cx="12" cy="12" r="5" fill="' . esc_attr( $foreground_color_pointer ) . '"/>
1973 + </svg>';
1974 +
1975 + // Only add the floor pointer flash SVG if floor_plan_direction_indicator is "on"
1976 + if ( $floor_plan_direction_indicator === 'on' ) {
1977 + $html .= '<svg class="floor-pointer-flash" width="54" height="35" viewBox="0 0 54 35" fill="none" xmlns="http://www.w3.org/2000/svg">
1978 + <path d="M0.454054 1.32433L11.7683 34.3243C11.9069 34.7285 12.287 35 12.7143 35H41.2857C41.713 35 42.0931 34.7285 42.2317 34.3243L53.5459 1.32432C53.7685 0.675257 53.2862 0 52.6 0H1.4C0.713843 0 0.231517 0.675258 0.454054 1.32433Z" fill="url(#paint0_linear_1_10)"/>
1979 + <defs>
1980 + <linearGradient id="paint0_linear_1_10" x1="27" y1="4.59807e-08" x2="26.5" y2="28" gradientUnits="userSpaceOnUse">
1981 + <stop stop-color="' . esc_attr( $floor_plan_custom_color ) . '" stop-opacity="0"/>
1982 + <stop offset="1" stop-color="' . esc_attr( $floor_plan_custom_color ) . '"/>
1983 + </linearGradient>
1984 + </defs>
1985 + </svg>';
1986 + }
1987 + $html .= '</div>';
1988 + }
1935 1989 $html .= '</div>';
1936 1990 }
1937 - $html .= '</div>';
1938 1991 //===Floor plan section===//
1939 1992
1940 1993 $html .= '<div class="wpvr-hotspot-tweak-contents-wrapper" style="display: none">';
1941 1994 $html .= '<i class="fa fa-times cross" data-id="' . $id . '"></i>';
@@ -2015,9 +2068,10 @@
2015 2068 border: '.$border_width.'px '.$border_style.' '.$border_color.';
2016 2069 border-radius: '.$border_radius.'px;
2017 2070 padding: '.$button_pt.'px '.$button_pr.'px '.$button_pb.'px '.$button_pl.'px;
2018 2071 ';
2019 - $html .= '<div class="wpvr-call-to-action-button position-'.$text_align.'" style="max-width:' . $width.'">
2072 + $cta_width = ( $width === 'fullwidth' || $width === 'embed' ) ? '100%' : $width;
2073 + $html .= '<div class="wpvr-call-to-action-button position-'.$text_align.'" style="max-width:' . $cta_width . '">
2020 2074 <a href="'.$buttonurl.'" style="'.$style.'" target="'.$target.'">'.$buttontext.'</a>
2021 2075 </div>';
2022 2076
2023 2077 }
@@ -2871,9 +2925,9 @@
2871 2925 $scene_key = $panoscenes['scene-id'];
2872 2926 $gallery_scene_ids[] = (string) $scene_key;
2873 2927 $scene_key_gallery = $panoscenes['scene-id'] . '_gallery_' . $pano_suffix;
2874 2928 $html .= 'jQuery(document).on("click","#' . $scene_key_gallery . '",function() {
2875 - panoshow' . $pano_suffix . '.loadScene("' . $scene_key . '");
2929 + panoshow' . $pano_suffix . '.loadScene(' . wp_json_encode( (string) $scene_key ) . ');
2876 2930 });';
2877 2931 }
2878 2932 }
2879 2933
@@ -3098,9 +3152,9 @@
3098 3152 $html .= '})();';
3099 3153 }
3100 3154 if ($custom_control['backToHomeSwitch'] == "on" && 'valid' == $status && $is_pro) {
3101 3155 $html .= 'document.getElementById("backToHome' . $pano_suffix . '").addEventListener("click", function(e) {';
3102 - $html .= 'panoshow' . $pano_suffix . '.loadScene("' . $default_scene . '");';
3156 + $html .= 'panoshow' . $pano_suffix . '.loadScene(' . wp_json_encode( (string) $default_scene ) . ');';
3103 3157 $html .= '});';
3104 3158 }
3105 3159 if ($gyro_button_enabled && 'valid' == $status && $is_pro) {
3106 3160 $html .= '
@@ -3209,11 +3263,15 @@
3209 3263 }
3210 3264
3211 3265 $html .= '
3212 3266 jQuery(document).on("click","#' . $panoid . '",function(event) {
3267 + var isCross = event.target.closest(".cross");
3213 3268 var isActiveModal = event.target.closest(".custom-ifram-wrapper");
3214 - var isForm = event.target.closest(".wpvr-hotspot-tweak-contents");
3269 + var isForm = event.target.closest(".wpvr-hotspot-tweak-contents-wrapper");
3215 3270 var isHotspot = event.target.closest(".pnlm-hotspot-base");
3271 + if(isCross != null){
3272 + return;
3273 + }
3216 3274 if(isForm != null){
3217 3275 jQuery(this).addClass("show-modal");
3218 3276 }else if(isActiveModal == null){
3219 3277 if(isHotspot == null){
@@ -3219,9 +3277,9 @@
3219 3277 if(isHotspot == null){
3220 3278 jQuery(".custom-ifram-wrapper .custom-ifram").empty();
3221 3279 jQuery(".custom-ifram-wrapper").hide();
3222 3280 jQuery(this).removeClass("show-modal");
3223 - jQuery(".wpvr-hotspot-tweak-contents-wrapper").hide("show-modal");
3281 + jQuery(".wpvr-hotspot-tweak-contents-wrapper").hide();
3224 3282 }
3225 3283 }
3226 3284 });';
3227 3285
@@ -3481,9 +3539,9 @@
3481 3539 window.wpvrViewers[response[0]["panoid"]] = panoshow' . $pano_suffix . ';
3482 3540 document.dispatchEvent(new CustomEvent("wpvr:viewer-ready", {
3483 3541 detail: { containerId: response[0]["panoid"], viewer: panoshow' . $pano_suffix . ' }
3484 3542 }));
3485 - jQuery("#' . $panoid . '").children(".pnlm-ui").find(".pnlm-load-button p").text("' . $previeword . '")
3543 + jQuery("#' . $panoid . '").children(".pnlm-ui").find(".pnlm-load-button p").text(' . wp_json_encode( (string) $previeword ) . ')
3486 3544 setTimeout(function() {
3487 3545 // panoshow' . $pano_suffix . '.loadScene("' . $default_scene . '");
3488 3546 window.dispatchEvent(new Event("resize"));
3489 3547 if (jQuery("#' . $panoid . '").children().children(".pnlm-panorama-info:visible").length > 0) {
@@ -3504,9 +3562,9 @@
3504 3562 document.dispatchEvent(new CustomEvent("wpvr:viewer-ready", {
3505 3563 detail: { containerId: response[0]["panoid"], viewer: panoshow' . $pano_suffix . ' }
3506 3564 }));
3507 3565 setTimeout(function() {
3508 - panoshow' . $pano_suffix . '.loadScene("' . $default_scene . '");
3566 + panoshow' . $pano_suffix . '.loadScene(' . wp_json_encode( (string) $default_scene ) . ');
3509 3567 window.dispatchEvent(new Event("resize"));
3510 3568 if (jQuery("#' . $panoid . '").children().children(".pnlm-panorama-info:visible").length > 0) {
3511 3569 jQuery("#controls' . $pano_suffix . '").css("bottom", "55px");
3512 3570 }
@@ -3516,9 +3574,9 @@
3516 3574 }, 200);
3517 3575 });';
3518 3576 if (isset($previeword) && $previeword != '') {
3519 3577 $html .= '
3520 - jQuery("#' . $panoid . '").children(".pnlm-ui").find(".pnlm-load-button p").text("' . $previeword . '")
3578 + jQuery("#' . $panoid . '").children(".pnlm-ui").find(".pnlm-load-button p").text(' . wp_json_encode( (string) $previeword ) . ')
3521 3579 ';
3522 3580 }
3523 3581 if ($default_global_zoom != '' || $max_global_zoom != '' || $min_global_zoom != '') {
3524 3582 $html .= 'jQuery(".globalzoom").val("on").change();';
@@ -3562,12 +3620,16 @@
3562 3620 private function sanitize_content_preserve_styles($content, $allow_forms = false) {
3563 3621 // Decode HTML entities first (in case content was encoded in database)
3564 3622 $content = html_entity_decode($content, ENT_QUOTES | ENT_HTML5, 'UTF-8');
3565 3623
3566 - // Escape <script> blocks to display as text instead of removing them
3567 - $content = preg_replace_callback('/<script\b[^>]*>(.*?)<\/script>/si', function($matches) {
3568 - return esc_html($matches[0]); // Convert to plain text
3569 - }, $content);
3624 + // Escape or strip <script> blocks
3625 + if ($allow_forms) {
3626 + $content = preg_replace('/<script\b[^>]*>[\s\S]*?<\/script>/i', '', $content);
3627 + } else {
3628 + $content = preg_replace_callback('/<script\b[^>]*>(.*?)<\/script>/si', function($matches) {
3629 + return esc_html($matches[0]); // Convert to plain text
3630 + }, $content);
3631 + }
3570 3632
3571 3633 // Strip dangerous URL-based attributes
3572 3634 $content = preg_replace('/(href|action|formaction)\s*=\s*["\']?\s*(javascript|vbscript|data|about):/i', '$1=""', $content);
3573 3635
@@ -3610,10 +3672,16 @@
3610 3672 $css = preg_replace('/-moz-binding\s*:/i', '', $css);
3611 3673 return '<style>' . esc_html($css) . '</style>';
3612 3674 }, $content);
3613 3675
3614 - // Allow iframes from safe sources only (e.g., YouTube, Vimeo)
3676 + // Allow iframes and styles from safe sources only
3615 3677 $allowed_tags = wp_kses_allowed_html('post');
3678 + $allowed_tags['style'] = [
3679 + 'type' => true,
3680 + 'id' => true,
3681 + 'class' => true,
3682 + 'media' => true,
3683 + ];
3616 3684 $allowed_tags['iframe'] = [
3617 3685 'src' => true,
3618 3686 'width' => true,
3619 3687 'height' => true,
@@ -3643,37 +3711,47 @@
3643 3711 ];
3644 3712
3645 3713 if ($allow_forms) {
3646 3714 $form_attributes = [
3647 - 'id' => true,
3648 - 'class' => true,
3649 - 'style' => true,
3650 - 'name' => true,
3651 - 'value' => true,
3652 - 'type' => true,
3653 - 'placeholder' => true,
3654 - 'action' => true,
3655 - 'method' => true,
3656 - 'target' => true,
3657 - 'enctype' => true,
3658 - 'disabled' => true,
3659 - 'readonly' => true,
3660 - 'required' => true,
3661 - 'checked' => true,
3662 - 'selected' => true,
3663 - 'multiple' => true,
3664 - 'size' => true,
3665 - 'rows' => true,
3666 - 'cols' => true,
3667 - 'maxlength' => true,
3668 - 'minlength' => true,
3669 - 'min' => true,
3670 - 'max' => true,
3671 - 'step' => true,
3672 - 'pattern' => true,
3673 - 'autocomplete'=> true,
3674 - 'autofocus' => true,
3675 - 'for' => true,
3715 + 'id' => true,
3716 + 'class' => true,
3717 + 'style' => true,
3718 + 'name' => true,
3719 + 'value' => true,
3720 + 'type' => true,
3721 + 'placeholder' => true,
3722 + 'action' => true,
3723 + 'method' => true,
3724 + 'target' => true,
3725 + 'enctype' => true,
3726 + 'disabled' => true,
3727 + 'readonly' => true,
3728 + 'required' => true,
3729 + 'checked' => true,
3730 + 'selected' => true,
3731 + 'multiple' => true,
3732 + 'size' => true,
3733 + 'rows' => true,
3734 + 'cols' => true,
3735 + 'maxlength' => true,
3736 + 'minlength' => true,
3737 + 'min' => true,
3738 + 'max' => true,
3739 + 'step' => true,
3740 + 'pattern' => true,
3741 + 'autocomplete' => true,
3742 + 'autofocus' => true,
3743 + 'for' => true,
3744 + 'data-*' => true,
3745 + 'data-form_id' => true,
3746 + 'data-form_instance' => true,
3747 + 'data-name' => true,
3748 + 'data-type' => true,
3749 + 'aria-invalid' => true,
3750 + 'aria-required' => true,
3751 + 'aria-label' => true,
3752 + 'aria-describedby' => true,
3753 + 'aria-labelledby' => true,
3676 3754 ];
3677 3755 $allowed_tags['form'] = $form_attributes;
3678 3756 $allowed_tags['input'] = $form_attributes;
3679 3757 $allowed_tags['button'] = $form_attributes;
@@ -3683,8 +3761,18 @@
3683 3761 $allowed_tags['optgroup'] = $form_attributes;
3684 3762 $allowed_tags['label'] = $form_attributes;
3685 3763 $allowed_tags['fieldset'] = $form_attributes;
3686 3764 $allowed_tags['legend'] = $form_attributes;
3765 + if (!isset($allowed_tags['div'])) {
3766 + $allowed_tags['div'] = [];
3767 + }
3768 + $allowed_tags['div']['data-*'] = true;
3769 + $allowed_tags['div']['data-form_id'] = true;
3770 + $allowed_tags['div']['data-form_instance'] = true;
3771 + if (!isset($allowed_tags['span'])) {
3772 + $allowed_tags['span'] = [];
3773 + }
3774 + $allowed_tags['span']['data-*'] = true;
3687 3775 }
3688 3776
3689 3777 // Apply wp_kses() to keep only allowed tags/attributes
3690 3778 $content = wp_kses($content, $allowed_tags);