mirror of
https://github.com/10h30/ultimatemember.git
synced 2026-07-11 18:56:10 +09:00
Merge pull request #1563 from ultimatemember/fix/textarea_html_on
Fix HTML formatted textarea
This commit is contained in:
@@ -1148,14 +1148,3 @@ small.um-max-filesize span{
|
||||
float: none;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.um-textarea-html-value {
|
||||
border: none;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: auto;
|
||||
max-height: none;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -96,18 +96,6 @@ UM.frontend = {
|
||||
UM.frontend.cropper.obj = null; // flush our own object
|
||||
}
|
||||
}
|
||||
},
|
||||
iframe: {
|
||||
resize: function(obj) {
|
||||
let newHeight;
|
||||
// 150 is default height of the iframe in web-browser
|
||||
if ( obj.contentWindow.document.documentElement.scrollHeight > 150 && obj.contentWindow.document.documentElement.scrollHeight > obj.contentWindow.document.documentElement.offsetHeight ) {
|
||||
newHeight = obj.contentWindow.document.documentElement.scrollHeight;
|
||||
} else {
|
||||
newHeight = obj.contentWindow.document.documentElement.offsetHeight;
|
||||
}
|
||||
obj.style.height = newHeight + 'px';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
"object"!=typeof window.UM&&(window.UM={}),"object"!=typeof UM.frontend&&(UM.frontend={}),UM.frontend={cropper:{obj:null,init:function(){var o=jQuery(".um-modal .um-single-image-preview img").first();if(o.length&&""!==o.attr("src")){UM.frontend.cropper.obj&&UM.frontend.cropper.destroy();var t=jQuery(".um-modal .um-single-image-preview"),n=o.parent().data("crop"),r=o.parent().data("min_width"),i=o.parent().data("min_height"),d=o.parent().data("ratio"),a=jQuery(".um-modal").find("#um_upload_single").data("ratio"),a=(a&&(d=a.split(":")[0]),jQuery(window).height()-(jQuery(".um-modal-footer a").height()+20)-50-jQuery(".um-modal-header:visible").height());o.css({height:"auto"}),t.css({height:"auto"}),jQuery(window).height()<=400?(t.css({height:a+"px","max-height":a+"px"}),o.css({height:"auto"})):(o.css({height:"auto","max-height":a+"px"}),t.css({height:o.height(),"max-height":a+"px"}));let e;"square"===n?e={minWidth:r,minHeight:i,dragCrop:!1,aspectRatio:1,zoomable:!1,rotatable:!1,dashed:!1}:"cover"===n?(0<Math.round(r/d)&&(i=Math.round(r/d)),e={minWidth:r,minHeight:i,dragCrop:!1,aspectRatio:d,zoomable:!1,rotatable:!1,dashed:!1}):"user"===n&&(e={minWidth:r,minHeight:i,dragCrop:!0,aspectRatio:"auto",zoomable:!1,rotatable:!1,dashed:!1}),e&&(UM.frontend.cropper.obj=new Cropper(o[0],e))}},destroy:function(){0<jQuery(".cropper-container").length&&UM.frontend.cropper.obj&&(UM.frontend.cropper.obj.destroy(),UM.frontend.cropper.obj=null)}},iframe:{resize:function(e){let o;o=150<e.contentWindow.document.documentElement.scrollHeight&&e.contentWindow.document.documentElement.scrollHeight>e.contentWindow.document.documentElement.offsetHeight?e.contentWindow.document.documentElement.scrollHeight:e.contentWindow.document.documentElement.offsetHeight,e.style.height=o+"px"}}},wp.hooks.addAction("um_remove_modal","um_common_frontend",function(){UM.frontend.cropper.destroy()}),wp.hooks.addAction("um_after_removing_preview","um_common_frontend",function(){UM.frontend.cropper.destroy()}),wp.hooks.addAction("um_window_resize","um_common_frontend",function(){UM.frontend.cropper.destroy()});
|
||||
"object"!=typeof window.UM&&(window.UM={}),"object"!=typeof UM.frontend&&(UM.frontend={}),UM.frontend={cropper:{obj:null,init:function(){var o=jQuery(".um-modal .um-single-image-preview img").first();if(o.length&&""!==o.attr("src")){UM.frontend.cropper.obj&&UM.frontend.cropper.destroy();var t=jQuery(".um-modal .um-single-image-preview"),r=o.parent().data("crop"),n=o.parent().data("min_width"),i=o.parent().data("min_height"),a=o.parent().data("ratio"),d=jQuery(".um-modal").find("#um_upload_single").data("ratio"),d=(d&&(a=d.split(":")[0]),jQuery(window).height()-(jQuery(".um-modal-footer a").height()+20)-50-jQuery(".um-modal-header:visible").height());o.css({height:"auto"}),t.css({height:"auto"}),jQuery(window).height()<=400?(t.css({height:d+"px","max-height":d+"px"}),o.css({height:"auto"})):(o.css({height:"auto","max-height":d+"px"}),t.css({height:o.height(),"max-height":d+"px"}));let e;"square"===r?e={minWidth:n,minHeight:i,dragCrop:!1,aspectRatio:1,zoomable:!1,rotatable:!1,dashed:!1}:"cover"===r?(0<Math.round(n/a)&&(i=Math.round(n/a)),e={minWidth:n,minHeight:i,dragCrop:!1,aspectRatio:a,zoomable:!1,rotatable:!1,dashed:!1}):"user"===r&&(e={minWidth:n,minHeight:i,dragCrop:!0,aspectRatio:"auto",zoomable:!1,rotatable:!1,dashed:!1}),e&&(UM.frontend.cropper.obj=new Cropper(o[0],e))}},destroy:function(){0<jQuery(".cropper-container").length&&UM.frontend.cropper.obj&&(UM.frontend.cropper.obj.destroy(),UM.frontend.cropper.obj=null)}}},wp.hooks.addAction("um_remove_modal","um_common_frontend",function(){UM.frontend.cropper.destroy()}),wp.hooks.addAction("um_after_removing_preview","um_common_frontend",function(){UM.frontend.cropper.destroy()}),wp.hooks.addAction("um_window_resize","um_common_frontend",function(){UM.frontend.cropper.destroy()});
|
||||
@@ -139,12 +139,4 @@ jQuery(document).ready(function() {
|
||||
jQuery( '.um-profile-nav a' ).on( 'touchend', function(e) {
|
||||
jQuery( e.currentTarget).trigger( "click" );
|
||||
});
|
||||
|
||||
let textarea_iframe = jQuery('iframe.um-textarea-html-value');
|
||||
textarea_iframe.each(function() {
|
||||
let obj = jQuery(this);
|
||||
obj.onload = function() {
|
||||
UM.frontend.iframe.resize(obj[0]);
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
jQuery(document).ready(function(){jQuery(".um-profile.um-viewing .um-profile-body .um-row").each(function(){var e=jQuery(this);0==e.find(".um-field").length&&(e.prev(".um-row-heading").remove(),e.remove())}),jQuery(".um-profile.um-viewing .um-profile-body").length&&0==jQuery(".um-profile.um-viewing .um-profile-body").find(".um-field").length&&(jQuery(".um-profile.um-viewing .um-profile-body").find(".um-row-heading,.um-row").remove(),jQuery(".um-profile-note").show()),jQuery(document.body).on("click",".um-profile-save",function(e){return e.preventDefault(),jQuery(this).parents(".um.um-profile.um-editing").find("form").trigger("submit"),!1}),jQuery(document.body).on("click",".um-profile-edit-a",function(e){jQuery(this).addClass("active")}),jQuery(document.body).on("click",".um-cover a.um-cover-add, .um-photo a",function(e){e.preventDefault()}),jQuery(document.body).on("click",".um-photo-modal",function(e){e.preventDefault();e=jQuery(this).attr("data-src");return um_new_modal("um_view_photo","fit",!0,e),!1}),jQuery(document.body).on("click",".um-reset-profile-photo",function(e){return jQuery(".um-profile-photo-img img").attr("src",jQuery(this).attr("data-default_src")),user_id=jQuery(this).attr("data-user_id"),metakey="profile_photo",UM.dropdown.hideAll(),jQuery.ajax({url:wp.ajax.settings.url,type:"post",data:{action:"um_delete_profile_photo",metakey:metakey,user_id:user_id,nonce:um_scripts.nonce}}),jQuery(this).parents("li").hide(),!1}),jQuery(document.body).on("click",".um-reset-cover-photo",function(e){var t=jQuery(this);return jQuery(".um-cover-overlay").hide(),jQuery(".um-cover-e").html('<a href="javascript:void(0);" class="um-cover-add" style="height: 370px;"><span class="um-cover-add-i"><i class="um-icon-plus um-tip-n" title="Upload a cover photo"></i></span></a>'),um_responsive(),user_id=jQuery(this).attr("data-user_id"),metakey="cover_photo",jQuery.ajax({url:wp.ajax.settings.url,type:"post",data:{action:"um_delete_cover_photo",metakey:metakey,user_id:user_id,nonce:um_scripts.nonce},success:function(e){t.hide()}}),UM.dropdown.hideAll(),!1}),jQuery(document.body).on("change keyup","#um-meta-bio",function(){if(void 0!==jQuery(this).val()){var t=jQuery(this).data("character-limit"),r=jQuery(this).data("html");let e=t-jQuery(this).val().length;e=(e=1===parseInt(r)?t-jQuery(this).val().replace(/(<([^>]+)>)/gi,"").length:e)<0?0:e,jQuery("span.um-meta-bio-character span.um-bio-limit").text(e);r=e<5?"red":"";jQuery("span.um-meta-bio-character").css("color",r)}}),jQuery("#um-meta-bio").trigger("change"),jQuery(".um-profile form").each(function(){let t=jQuery(this).data("description_key");jQuery(this).find('textarea[name="'+t+'"]').length&&jQuery(document.body).on("change input",'textarea[name="'+t+'"]',function(e){jQuery(this).parents("form").find('textarea[name="'+t+'"]').each(function(){jQuery(this).val(e.currentTarget.value),jQuery("#um-meta-bio")[0]!==e.currentTarget&&jQuery("#um-meta-bio")[0]===jQuery(this)[0]&&jQuery(this).trigger("change")})})}),jQuery(".um-profile-edit a.um_delete-item").on("click",function(e){if(e.preventDefault(),!confirm(wp.i18n.__("Are you sure that you want to delete this user?","ultimate-member")))return!1}),jQuery(".um-profile-nav a").on("touchend",function(e){jQuery(e.currentTarget).trigger("click")}),jQuery("iframe.um-textarea-html-value").each(function(){let e=jQuery(this);e.onload=function(){UM.frontend.iframe.resize(e[0])}})});
|
||||
jQuery(document).ready(function(){jQuery(".um-profile.um-viewing .um-profile-body .um-row").each(function(){var e=jQuery(this);0==e.find(".um-field").length&&(e.prev(".um-row-heading").remove(),e.remove())}),jQuery(".um-profile.um-viewing .um-profile-body").length&&0==jQuery(".um-profile.um-viewing .um-profile-body").find(".um-field").length&&(jQuery(".um-profile.um-viewing .um-profile-body").find(".um-row-heading,.um-row").remove(),jQuery(".um-profile-note").show()),jQuery(document.body).on("click",".um-profile-save",function(e){return e.preventDefault(),jQuery(this).parents(".um.um-profile.um-editing").find("form").trigger("submit"),!1}),jQuery(document.body).on("click",".um-profile-edit-a",function(e){jQuery(this).addClass("active")}),jQuery(document.body).on("click",".um-cover a.um-cover-add, .um-photo a",function(e){e.preventDefault()}),jQuery(document.body).on("click",".um-photo-modal",function(e){e.preventDefault();e=jQuery(this).attr("data-src");return um_new_modal("um_view_photo","fit",!0,e),!1}),jQuery(document.body).on("click",".um-reset-profile-photo",function(e){return jQuery(".um-profile-photo-img img").attr("src",jQuery(this).attr("data-default_src")),user_id=jQuery(this).attr("data-user_id"),metakey="profile_photo",UM.dropdown.hideAll(),jQuery.ajax({url:wp.ajax.settings.url,type:"post",data:{action:"um_delete_profile_photo",metakey:metakey,user_id:user_id,nonce:um_scripts.nonce}}),jQuery(this).parents("li").hide(),!1}),jQuery(document.body).on("click",".um-reset-cover-photo",function(e){var t=jQuery(this);return jQuery(".um-cover-overlay").hide(),jQuery(".um-cover-e").html('<a href="javascript:void(0);" class="um-cover-add" style="height: 370px;"><span class="um-cover-add-i"><i class="um-icon-plus um-tip-n" title="Upload a cover photo"></i></span></a>'),um_responsive(),user_id=jQuery(this).attr("data-user_id"),metakey="cover_photo",jQuery.ajax({url:wp.ajax.settings.url,type:"post",data:{action:"um_delete_cover_photo",metakey:metakey,user_id:user_id,nonce:um_scripts.nonce},success:function(e){t.hide()}}),UM.dropdown.hideAll(),!1}),jQuery(document.body).on("change keyup","#um-meta-bio",function(){if(void 0!==jQuery(this).val()){var t=jQuery(this).data("character-limit"),r=jQuery(this).data("html");let e=t-jQuery(this).val().length;e=(e=1===parseInt(r)?t-jQuery(this).val().replace(/(<([^>]+)>)/gi,"").length:e)<0?0:e,jQuery("span.um-meta-bio-character span.um-bio-limit").text(e);r=e<5?"red":"";jQuery("span.um-meta-bio-character").css("color",r)}}),jQuery("#um-meta-bio").trigger("change"),jQuery(".um-profile form").each(function(){let t=jQuery(this).data("description_key");jQuery(this).find('textarea[name="'+t+'"]').length&&jQuery(document.body).on("change input",'textarea[name="'+t+'"]',function(e){jQuery(this).parents("form").find('textarea[name="'+t+'"]').each(function(){jQuery(this).val(e.currentTarget.value),jQuery("#um-meta-bio")[0]!==e.currentTarget&&jQuery("#um-meta-bio")[0]===jQuery(this)[0]&&jQuery(this).trigger("change")})})}),jQuery(".um-profile-edit a.um_delete-item").on("click",function(e){if(e.preventDefault(),!confirm(wp.i18n.__("Are you sure that you want to delete this user?","ultimate-member")))return!1}),jQuery(".um-profile-nav a").on("touchend",function(e){jQuery(e.currentTarget).trigger("click")})});
|
||||
@@ -21,6 +21,7 @@
|
||||
"ext-fileinfo": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-iconv": "*",
|
||||
"ext-tidy": "*",
|
||||
"woocommerce/action-scheduler": "3.2.1"
|
||||
},
|
||||
"require-dev": {
|
||||
|
||||
@@ -736,6 +736,59 @@ if ( ! class_exists( 'um\core\Form' ) ) {
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use PHP tidy extension if it's active for getting clean HTML without unclosed tags.
|
||||
*
|
||||
* @param string $html_fragment Textarea with active HTML option field value.
|
||||
* @param array $field_data Ultimate Member form field data.
|
||||
*
|
||||
* @return string|\tidy
|
||||
*/
|
||||
private static function maybe_apply_tidy( $html_fragment, $field_data ) {
|
||||
// Break if extension isn't active in php.ini
|
||||
if ( ! function_exists( 'tidy_parse_string' ) ) {
|
||||
return $html_fragment;
|
||||
}
|
||||
|
||||
$tidy_config = array(
|
||||
'clean' => true,
|
||||
'output-xhtml' => true,
|
||||
'show-body-only' => true,
|
||||
'wrap' => 0,
|
||||
);
|
||||
/**
|
||||
* Filters PHP tidy extension config.
|
||||
* Get more info here https://www.php.net/manual/en/tidy.parsestring.php
|
||||
*
|
||||
* @param {array} $tidy_config Config.
|
||||
* @param {array} $field_data UM Form Field Data.
|
||||
*
|
||||
* @return {array} Config.
|
||||
*
|
||||
* @since 2.8.9
|
||||
* @hook um_tidy_config
|
||||
*
|
||||
* @example <caption>Customize tidy config based on field data.</caption>
|
||||
* function my_um_tidy_config( $tidy_config, $field_data ) {
|
||||
* // your code here
|
||||
* if ( 'custom_metakey' === $field_data['metakey'] ) {
|
||||
* $tidy_config['clean'] = false;
|
||||
* }
|
||||
* return $tidy_config;
|
||||
* }
|
||||
* add_filter( 'um_tidy_config', 'my_um_tidy_config', 10, 2 );
|
||||
*/
|
||||
$tidy_config = apply_filters( 'um_tidy_config', $tidy_config, $field_data );
|
||||
|
||||
// since PHP8.0 $tidy_config, 'UTF8' variables are nullable https://www.php.net/manual/en/tidy.parsestring.php
|
||||
$tidy = tidy_parse_string( $html_fragment, $tidy_config, 'UTF8' );
|
||||
$result = $tidy->cleanRepair();
|
||||
if ( $result ) {
|
||||
return $tidy;
|
||||
}
|
||||
|
||||
return $html_fragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Beautify form data
|
||||
@@ -770,6 +823,8 @@ if ( ! class_exists( 'um\core\Form' ) ) {
|
||||
$form[ $k ] = $match[1];
|
||||
}
|
||||
|
||||
$form[ $k ] = self::maybe_apply_tidy( $form[ $k ], $field );
|
||||
|
||||
$allowed_html = UM()->get_allowed_html( 'templates' );
|
||||
if ( empty( $allowed_html['iframe'] ) ) {
|
||||
$allowed_html['iframe'] = array(
|
||||
@@ -907,6 +962,14 @@ if ( ! class_exists( 'um\core\Form' ) ) {
|
||||
if ( array_key_exists( $description_key, $custom_fields ) ) {
|
||||
$field_exists = true;
|
||||
if ( ! empty( $custom_fields[ $description_key ]['html'] ) && $bio_html ) {
|
||||
$form[ $description_key ] = html_entity_decode( $form[ $description_key ] ); // required because WP_Editor send sometimes encoded content.
|
||||
preg_match( '/^<p>(.*?)<\/p>$/', $form[ $description_key ], $match ); // required because WP_Editor send content wrapped to <p></p>
|
||||
if ( ! empty( $match[1] ) ) {
|
||||
$form[ $description_key ] = $match[1];
|
||||
}
|
||||
|
||||
$form[ $description_key ] = self::maybe_apply_tidy( $form[ $description_key ], $custom_fields[ $description_key ] );
|
||||
|
||||
$allowed_html = UM()->get_allowed_html( 'templates' );
|
||||
if ( empty( $allowed_html['iframe'] ) ) {
|
||||
$allowed_html['iframe'] = array(
|
||||
|
||||
@@ -261,7 +261,7 @@ function um_profile_field_filter_hook__textarea( $value, $data ) {
|
||||
}
|
||||
|
||||
if ( ! empty( $data['html'] ) ) {
|
||||
return '<iframe class="um-textarea-html-value" onload="UM.frontend.iframe.resize(this);" title="' . esc_attr( $data['label'] ) . '" srcdoc="' . wp_kses_post( esc_attr( $value ) ) . '"></iframe>';
|
||||
return wp_kses_post( $value );
|
||||
}
|
||||
|
||||
$description_key = UM()->profile()->get_show_bio_key( UM()->fields()->global_args );
|
||||
|
||||
+12
@@ -166,6 +166,18 @@ No specific extensions are needed. But we highly recommended keep active these P
|
||||
|
||||
IMPORTANT: PLEASE UPDATE THE PLUGIN TO AT LEAST VERSION 2.6.7 IMMEDIATELY. VERSION 2.6.7 PATCHES SECURITY PRIVILEGE ESCALATION VULNERABILITY. PLEASE SEE [THIS ARTICLE](https://docs.ultimatemember.com/article/1866-security-incident-update-and-recommended-actions) FOR MORE INFORMATION
|
||||
|
||||
= 2.8.9 2024-10-14 =
|
||||
|
||||
**Enhancements**
|
||||
|
||||
* Added: Using PHP tidy extension (if it's active) to make HTML textarea value clear
|
||||
* Added: `um_tidy_config` filter hook for setting PHP tidy config
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
* Fixed: UM tipsy removing inside .um-page selector (e.g. tipsy init from um-modal)
|
||||
* Fixed: Rollback using `<iframe>` for displaying HTML formatted textarea value
|
||||
|
||||
= 2.8.8 2024-10-04 =
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
Reference in New Issue
Block a user