← All changes
|
includes/page-form-builder/form-settings/_src/settings_effects.js
+160
-11
11.4
→
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( |