PluginProbe
Booking Calendar / 11.9
Booking Calendar v11.9
11.9 11.8.4 11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 All 205 releases
← All changes | includes/page-form-builder/form-settings/_src/settings_effects.js +160 -11 11.4.1 → 11.9 View file →
@@ -370,11 +370,39 @@
370 370 function wpbc_bfb_form_appearance__sanitize_optional_color(value) {
371 371 return wpbc_bfb_form_appearance__sanitize_color( value, '' );
372 372 }
373 373
374 +/**
375 + * Resolve an opaque accent color with the PHP-localized installation default.
376 + *
377 + * The Form Style effects live outside the registration IIFE, so the default is
378 + * deliberately read from the shared localized payload at the point of use.
379 + * Invalid requested and localized values return an empty string, allowing the
380 + * caller to skip the accent overlay without throwing or producing invalid CSS.
381 + *
382 + * @param {*} value Requested accent color.
383 + * @return {string} Valid three- or six-digit hexadecimal color, or an empty string.
384 + */
385 +function wpbc_bfb_global_form_style__sanitize_accent_color(value) {
386 + const requested_color = String( value == null ? '' : value ).trim();
387 + if ( /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.test( requested_color ) ) {
388 + return requested_color;
389 + }
390 +
391 + const settings_vars = window.wpbc_bfb_settings_vars && typeof window.wpbc_bfb_settings_vars === 'object'
392 + ? window.wpbc_bfb_settings_vars
393 + : {};
394 + const accent_defaults = settings_vars.form_accent_defaults && typeof settings_vars.form_accent_defaults === 'object'
395 + ? settings_vars.form_accent_defaults
396 + : {};
397 + const default_color = String( accent_defaults.booking_form_accent_color || '' ).trim();
398 +
399 + return /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.test( default_color ) ? default_color : '';
400 +}
401 +
374 402 function wpbc_bfb_form_appearance__sanitize_length(value, fallback) {
375 403 const v = String( value == null ? '' : value ).trim();
376 - if ( /^-?\d+(?:\.\d+)?(?:px|rem|em|%)$/i.test( v ) ) {
404 + if ( /^\d+(?:\.\d+)?(?:px|rem|em|%)$/i.test( v ) ) {
377 405 return v;
378 406 }
379 407 return fallback;
380 408 }
@@ -385,9 +413,9 @@
385 413 if ( parts.length < 1 || parts.length > 4 ) {
386 414 return fallback;
387 415 }
388 416 for ( let i = 0; i < parts.length; i++ ) {
389 - if ( ! /^-?\d+(?:\.\d+)?(?:px|rem|em|%)$/i.test( parts[i] ) ) {
417 + if ( ! /^\d+(?:\.\d+)?(?:px|rem|em|%)$/i.test( parts[i] ) ) {
390 418 return fallback;
391 419 }
392 420 }
393 421 return parts.join( ' ' );
@@ -395,10 +423,10 @@
395 423
396 424 function wpbc_bfb_form_appearance__normalize_spacing_numbers(vertical, horizontal) {
397 425 const v = String( vertical == null ? '' : vertical ).trim();
398 426 const h = String( horizontal == null ? '' : horizontal ).trim();
399 - const vertical_num = /^-?\d+(?:\.\d+)?$/.test( v ) ? v : '0';
400 - const horizontal_num = /^-?\d+(?:\.\d+)?$/.test( h ) ? h : vertical_num;
427 + const vertical_num = /^\d+(?:\.\d+)?$/.test( v ) ? v : '0';
428 + const horizontal_num = /^\d+(?:\.\d+)?$/.test( h ) ? h : vertical_num;
401 429
402 430 return vertical_num + 'px ' + horizontal_num + 'px';
403 431 }
404 432
@@ -737,9 +765,11 @@
737 765 'booking_form_custom_secondary_button_text_color',
738 766 'booking_form_custom_secondary_button_border_color',
739 767 'booking_form_custom_secondary_button_hover_background_color',
740 768 'booking_form_custom_secondary_button_hover_text_color',
741 - 'booking_form_custom_secondary_button_hover_border_color'
769 + 'booking_form_custom_secondary_button_hover_border_color',
770 + 'booking_form_custom_button_border_width',
771 + 'booking_form_custom_button_border_radius'
742 772 ];
743 773 }
744 774
745 775 function wpbc_bfb_global_form_style__get_custom_defaults() {
@@ -769,9 +799,11 @@
769 799 booking_form_custom_secondary_button_text_color: '#444444',
770 800 booking_form_custom_secondary_button_border_color: '#eeeeee',
771 801 booking_form_custom_secondary_button_hover_background_color: '#fdfdfd',
772 802 booking_form_custom_secondary_button_hover_text_color: '#444444',
773 - booking_form_custom_secondary_button_hover_border_color: '#4d91cd'
803 + booking_form_custom_secondary_button_hover_border_color: '#4d91cd',
804 + booking_form_custom_button_border_width : '1px',
805 + booking_form_custom_button_border_radius : '3px'
774 806 }, localized );
775 807 }
776 808
777 809 function wpbc_bfb_global_form_style__get_current_options(ctx, key, value) {
@@ -796,8 +828,105 @@
796 828
797 829 return options;
798 830 }
799 831
832 +function wpbc_bfb_global_form_style__mix_colors(color, target, amount) {
833 + let source = wpbc_bfb_global_form_style__sanitize_accent_color( color ).replace( '#', '' );
834 + const destination = wpbc_bfb_form_appearance__sanitize_color( target, '#000000' ).replace( '#', '' );
835 + const channels = [];
836 + if ( ! source ) {
837 + return '';
838 + }
839 + if ( source.length === 3 ) {
840 + source = source.replace( /./g, function (value) { return value + value; } );
841 + }
842 + for ( let index = 0; index < 3; index++ ) {
843 + const source_channel = parseInt( source.substr( index * 2, 2 ), 16 );
844 + const target_channel = parseInt( destination.substr( index * 2, 2 ), 16 );
845 + channels.push( Math.round( source_channel + ( ( target_channel - source_channel ) * amount ) ) );
846 + }
847 + return '#' + channels.map( function (channel) { return ( '0' + channel.toString( 16 ) ).slice( -2 ); } ).join( '' );
848 +}
849 +
850 +function wpbc_bfb_global_form_style__get_luminance(color) {
851 + let hex = wpbc_bfb_global_form_style__sanitize_accent_color( color ).replace( '#', '' );
852 + if ( ! hex ) {
853 + return 0;
854 + }
855 + if ( hex.length === 3 ) {
856 + hex = hex.replace( /./g, function (value) { return value + value; } );
857 + }
858 + const channels = [ 0, 1, 2 ].map( function (index) {
859 + const channel = parseInt( hex.substr( index * 2, 2 ), 16 ) / 255;
860 + return channel <= 0.03928 ? channel / 12.92 : Math.pow( ( channel + 0.055 ) / 1.055, 2.4 );
861 + } );
862 + return ( 0.2126 * channels[0] ) + ( 0.7152 * channels[1] ) + ( 0.0722 * channels[2] );
863 +}
864 +
865 +/**
866 + * Apply shared accent variables without masking explicit Custom button controls.
867 + *
868 + * @param {Object} css_vars Resolved base style variables.
869 + * @param {Object} options Current global style options.
870 + * @param {boolean} preserve_custom_button_colors Whether Custom button variables remain authoritative.
871 + * @return {Object} Resolved variables with the optional accent overlay.
872 + */
873 +function wpbc_bfb_global_form_style__apply_accent(css_vars, options, preserve_custom_button_colors) {
874 + if ( String( options.booking_form_accent_enabled || 'Off' ) !== 'On' ) {
875 + return css_vars;
876 + }
877 + const accent = wpbc_bfb_global_form_style__sanitize_accent_color( options.booking_form_accent_color );
878 + if ( ! accent ) {
879 + return css_vars;
880 + }
881 + const luminance = wpbc_bfb_global_form_style__get_luminance( accent );
882 + const contrast = luminance > 0.18 ? '#000000' : '#ffffff';
883 + const hover_target = '#ffffff' === contrast ? '#000000' : '#ffffff';
884 + const hover = wpbc_bfb_global_form_style__mix_colors( accent, hover_target, 0.10 );
885 + const hover_contrast = contrast;
886 +
887 + const accent_overlay = {
888 + '--wpbc_form-accent-color': accent,
889 + '--wpbc_form-accent-hover-color': hover,
890 + '--wpbc_form-accent-contrast-color': contrast,
891 + '--wpbc_form-field-focus-border-color': accent,
892 + '--wpbc_form-field-focus-shadow-color': accent,
893 + '--wpbc_form-choice-checked-border-color': accent,
894 + '--wpbc_form-choice-checked-color': accent,
895 + '--wpbc_form-choice-focus-color': accent,
896 + '--wpbc_form-button-background-color': accent,
897 + '--wpbc_form-button-background-color-alt': accent,
898 + '--wpbc_form-button-border-color': accent,
899 + '--wpbc_form-button-text-color': contrast,
900 + '--wpbc_form-button-text-color-alt': contrast,
901 + '--wpbc_form-button-hover-background-color': hover,
902 + '--wpbc_form-button-hover-border-color': hover,
903 + '--wpbc_form-button-hover-text-color': hover_contrast,
904 + '--wpbc_form-button-light-hover-border-color': accent,
905 + '--wpbc_form-button-primary-hover-border-color': hover,
906 + '--wpbc_form-page-break-color': accent
907 + };
908 +
909 + if ( preserve_custom_button_colors ) {
910 + [
911 + '--wpbc_form-button-background-color',
912 + '--wpbc_form-button-background-color-alt',
913 + '--wpbc_form-button-border-color',
914 + '--wpbc_form-button-text-color',
915 + '--wpbc_form-button-text-color-alt',
916 + '--wpbc_form-button-hover-background-color',
917 + '--wpbc_form-button-hover-border-color',
918 + '--wpbc_form-button-hover-text-color',
919 + '--wpbc_form-button-light-hover-border-color',
920 + '--wpbc_form-button-primary-hover-border-color'
921 + ].forEach( function (css_var_name) {
922 + delete accent_overlay[css_var_name];
923 + } );
924 + }
925 +
926 + return Object.assign( {}, css_vars, accent_overlay );
927 +}
928 +
800 929 function wpbc_bfb_global_form_style__resolve_css_vars(options) {
801 930 options = options && typeof options === 'object' ? options : {};
802 931 const style = String( options.booking_form_style || 'light_bordered' );
803 932 const presets = wpbc_bfb_global_form_style__get_presets();
@@ -804,12 +933,12 @@
804 933 const preset = presets[style] || presets.light_bordered || {};
805 934 const defaults = wpbc_bfb_global_form_style__get_custom_defaults();
806 935
807 936 if ( 'custom' !== style ) {
808 - return preset.css_vars && typeof preset.css_vars === 'object' ? Object.assign( {}, preset.css_vars ) : {};
937 + return wpbc_bfb_global_form_style__apply_accent( preset.css_vars && typeof preset.css_vars === 'object' ? Object.assign( {}, preset.css_vars ) : {}, options );
809 938 }
810 939
811 - return {
940 + const css_vars = {
812 941 '--wpbc-bfb-form-background' : wpbc_bfb_form_appearance__sanitize_color( options.booking_form_custom_background_color, defaults.booking_form_custom_background_color ),
813 942 '--wpbc-bfb-form-border-color' : wpbc_bfb_form_appearance__sanitize_color( options.booking_form_custom_border_color, defaults.booking_form_custom_border_color ),
814 943 '--wpbc-bfb-form-border-width' : wpbc_bfb_form_appearance__sanitize_length( options.booking_form_custom_border_width, defaults.booking_form_custom_border_width ),
815 944 '--wpbc-bfb-form-border-radius' : wpbc_bfb_form_appearance__sanitize_length( options.booking_form_custom_border_radius, defaults.booking_form_custom_border_radius ),
@@ -825,8 +954,11 @@
825 954 '--wpbc_form-field-border-color-spare': wpbc_bfb_form_appearance__sanitize_color( options.booking_form_custom_field_border_color, defaults.booking_form_custom_field_border_color ),
826 955 '--wpbc_form-field-focus-border-color': '#066aab',
827 956 '--wpbc_form-field-focus-shadow-color': '#066aab',
828 957 '--wpbc_form-field-disabled-color' : 'rgba(0, 0, 0, 0.2)',
958 + '--wpbc_form-button-border-radius' : wpbc_bfb_form_appearance__sanitize_length( options.booking_form_custom_button_border_radius, defaults.booking_form_custom_button_border_radius ),
959 + '--wpbc_form-button-border-style' : 'solid',
960 + '--wpbc_form-button-border-size' : wpbc_bfb_form_appearance__sanitize_length( options.booking_form_custom_button_border_width, defaults.booking_form_custom_button_border_width ),
829 961 '--wpbc_form-button-background-color' : wpbc_bfb_form_appearance__sanitize_color( options.booking_form_custom_button_background_color, defaults.booking_form_custom_button_background_color ),
830 962 '--wpbc_form-button-background-color-alt': wpbc_bfb_form_appearance__sanitize_color( options.booking_form_custom_button_background_color, defaults.booking_form_custom_button_background_color ),
831 963 '--wpbc_form-button-border-color' : wpbc_bfb_form_appearance__sanitize_color( options.booking_form_custom_button_border_color, defaults.booking_form_custom_button_border_color ),
832 964 '--wpbc_form-button-text-color' : wpbc_bfb_form_appearance__sanitize_color( options.booking_form_custom_button_text_color, defaults.booking_form_custom_button_text_color ),
@@ -838,8 +970,9 @@
838 970 '--wpbc_form-choice-checked-color' : '#066aab',
839 971 '--wpbc_form-choice-focus-color' : '#066aab',
840 972 '--wpbc_form-button-light-background-color': wpbc_bfb_form_appearance__sanitize_color( options.booking_form_custom_secondary_button_background_color, defaults.booking_form_custom_secondary_button_background_color ),
841 973 '--wpbc_form-button-light-border-color': wpbc_bfb_form_appearance__sanitize_color( options.booking_form_custom_secondary_button_border_color, defaults.booking_form_custom_secondary_button_border_color ),
974 + '--wpbc_form-button-light-border-size': wpbc_bfb_form_appearance__sanitize_length( options.booking_form_custom_button_border_width, defaults.booking_form_custom_button_border_width ),
842 975 '--wpbc_form-button-light-text-color' : wpbc_bfb_form_appearance__sanitize_color( options.booking_form_custom_secondary_button_text_color, defaults.booking_form_custom_secondary_button_text_color ),
843 976 '--wpbc_form-button-light-box-shadow' : '0 2px 10px 2px #ffffff54',
844 977 '--wpbc_form-button-light-hover-background-color': wpbc_bfb_form_appearance__sanitize_color( options.booking_form_custom_secondary_button_hover_background_color, defaults.booking_form_custom_secondary_button_hover_background_color ),
845 978 '--wpbc_form-button-light-hover-border-color': wpbc_bfb_form_appearance__sanitize_color( options.booking_form_custom_secondary_button_hover_border_color, defaults.booking_form_custom_secondary_button_hover_border_color ),
@@ -847,8 +980,10 @@
847 980 '--wpbc_form-button-light-hover-box-shadow': '0 2px 10px 2px #ffffff54',
848 981 '--wpbc_form-button-primary-hover-border-color': wpbc_bfb_form_appearance__sanitize_color( options.booking_form_custom_button_hover_border_color, defaults.booking_form_custom_button_hover_border_color ),
849 982 '--wpbc_form-page-break-color' : '#066aab'
850 983 };
984 +
985 + return wpbc_bfb_global_form_style__apply_accent( css_vars, options, true );
851 986 }
852 987
853 988 function wpbc_bfb_global_form_style__get_css_var_keys(options) {
854 989 const vars = wpbc_bfb_global_form_style__get_vars();
@@ -881,8 +1016,9 @@
881 1016 }
882 1017
883 1018 function wpbc_bfb_global_form_style__sync_controls(options) {
884 1019 const is_custom = 'custom' === String( options && options.booking_form_style ? options.booking_form_style : '' );
1020 + const accent_enabled = 'On' === String( options && options.booking_form_accent_enabled ? options.booking_form_accent_enabled : 'Off' );
885 1021 const reset_row = document.querySelector( '[data-wpbc-bfb-custom-appearance-reset-row]' );
886 1022
887 1023 wpbc_bfb_form_appearance__set_radio_control( 'booking_form_style', options.booking_form_style || 'light_bordered' );
888 1024
@@ -891,8 +1027,14 @@
891 1027 row.setAttribute( 'aria-hidden', is_custom ? 'false' : 'true' );
892 1028 row.classList.toggle( 'is-hidden', ! is_custom );
893 1029 } );
894 1030
1031 + document.querySelectorAll( '.wpbc_bfb__form_setting_global_accent_dependent' ).forEach( function (row) {
1032 + row.hidden = ! accent_enabled;
1033 + row.setAttribute( 'aria-hidden', accent_enabled ? 'false' : 'true' );
1034 + row.classList.toggle( 'is-hidden', ! accent_enabled );
1035 + } );
1036 +
895 1037 if ( reset_row ) {
896 1038 reset_row.hidden = ! is_custom;
897 1039 reset_row.setAttribute( 'aria-hidden', is_custom ? 'false' : 'true' );
898 1040 reset_row.classList.toggle( 'is-hidden', ! is_custom );
@@ -904,9 +1046,12 @@
904 1046 const style = String( options.booking_form_style || 'light_bordered' );
905 1047 const presets = wpbc_bfb_global_form_style__get_presets();
906 1048 const preset = presets[style] || presets.light_bordered || {};
907 1049 const css_vars = wpbc_bfb_global_form_style__resolve_css_vars( options );
908 - const root = ( ctx && ctx.canvas ) || document.getElementById( 'wpbc_bfb__theme_scope' ) || document;
1050 + // Form Style is global. Always start at the complete Builder theme scope so
1051 + // inline Custom tokens on an outer wrapper cannot leak into a preset when a
1052 + // field-level update provides only the inner canvas in ctx.canvas.
1053 + const root = document.getElementById( 'wpbc_bfb__theme_scope' ) || ( ctx && ctx.canvas ) || document;
909 1054 const theme_classes = [];
910 1055 const css_var_keys = wpbc_bfb_global_form_style__get_css_var_keys( options );
911 1056
912 1057 wpbc_bfb_global_form_style__sync_controls( options );
@@ -953,8 +1098,10 @@
953 1098 }
954 1099
955 1100 [
956 1101 'booking_form_style',
1102 + 'booking_form_accent_enabled',
1103 + 'booking_form_accent_color',
957 1104 'booking_form_custom_background_color',
958 1105 'booking_form_custom_border_color',
959 1106 'booking_form_custom_border_width',
960 1107 'booking_form_custom_border_radius',
@@ -974,9 +1121,11 @@
974 1121 'booking_form_custom_secondary_button_text_color',
975 1122 'booking_form_custom_secondary_button_border_color',
976 1123 'booking_form_custom_secondary_button_hover_background_color',
977 1124 'booking_form_custom_secondary_button_hover_text_color',
978 - 'booking_form_custom_secondary_button_hover_border_color'
1125 + 'booking_form_custom_secondary_button_hover_border_color',
1126 + 'booking_form_custom_button_border_width',
1127 + 'booking_form_custom_button_border_radius'
979 1128 ].forEach( function (key) {
980 1129 WPBC_BFB_Settings_Effects.register( key, function (value, ctx) {
981 1130 wpbc_bfb_global_form_style__apply( value, Object.assign( {}, ctx || {}, { key: key } ) );
982 1131 } );
@@ -1058,9 +1207,9 @@
1058 1207
1059 1208 const v = String( value == null ? '' : value ).trim();
1060 1209
1061 1210 // allow only "number + unit".
1062 - if ( v && ! /^-?\d+(?:\.\d+)?(?:%|px|rem|em|vw|vh)$/.test( v ) ) {
1211 + if ( v && ! /^\d+(?:\.\d+)?(?:%|px|rem|em|vw|vh)$/.test( v ) ) {
1063 1212 return;
1064 1213 }
1065 1214
1066 1215 wraps.forEach(