Plugin Directory

Changeset 3456321


Ignore:
Timestamp:
02/08/2026 10:11:04 AM (4 weeks ago)
Author:
griffinforms
Message:

Release 2.3.1.0

Location:
griffinforms-form-builder
Files:
1783 added
15 edited

Legend:

Unmodified
Added
Removed
  • griffinforms-form-builder/trunk/admin/css/app/griffinforms-app-formlayout.css

    r3450618 r3456321  
    7272    -webkit-appearance: none !important;
    7373    -moz-appearance: none !important;
    74     background-image: none !important;
     74    background-image: var(--gf-phone-caret-image, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpolyline points='2,4 6,8 10,4' fill='none' stroke='%236c757d' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")) !important;
     75    background-position: calc(100% - 14px) 50% !important;
     76    background-size: 12px 12px !important;
    7577    background-repeat: no-repeat !important;
     78    padding-right: 44px !important;
    7679}
    7780
     
    119122    width: 1% !important;
    120123    min-width: 0 !important;
     124}
     125
     126@media (max-width: 575.98px) {
     127    #griffinforms-app-presentationarea .griffinforms-app-formlayout-form:not(.gf-no-theme) .griffinforms-app-field-form_control .griffinforms-phone-input-group .griffinforms-phone-country-select.form-select[data-gf-phone-display-mode="code_only"] {
     128        background-image: none !important;
     129        padding-right: 12px !important;
     130    }
    121131}
    122132
  • griffinforms-form-builder/trunk/admin/css/app/griffinforms-app-no-theme.css

    r3450618 r3456321  
    6363  -webkit-appearance: none !important;
    6464  -moz-appearance: none !important;
    65   background-image: none !important;
     65  background-image: var(--gf-phone-caret-image, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpolyline points='2,4 6,8 10,4' fill='none' stroke='%236c757d' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")) !important;
     66  background-position: calc(100% - 14px) 50% !important;
     67  background-size: 12px 12px !important;
    6668  background-repeat: no-repeat !important;
     69  padding-right: 44px !important;
    6770  background-color: rgba(0, 0, 0, 0.05) !important;
    6871}
     
    107110  width: 1% !important;
    108111  min-width: 0 !important;
     112}
     113
     114@media (max-width: 575.98px) {
     115  .griffinforms-app-formlayout-form .gf-no-theme .griffinforms-app-field-form_control .griffinforms-phone-input-group .griffinforms-phone-country-select.form-select[data-gf-phone-display-mode="code_only"] {
     116    background-image: none !important;
     117    padding-right: 12px !important;
     118  }
    109119}
    110120
  • griffinforms-form-builder/trunk/admin/css/overrides.css

    r3450618 r3456321  
    2727  z-index: 2;
    2828  flex: 0 0 28%;
    29   max-width: 28%;
     29  max-width: 180px;
     30  padding-right: 44px;
    3031  border-right-width: var(--gf-phone-border-width, 1px) !important;
    3132  border-right-style: var(--gf-phone-border-style, solid) !important;
    3233  border-right-color: var(--gf-phone-border-color, #dee2e6) !important;
    33   box-shadow: inset -1px 0 0 var(--gf-phone-border-color, #dee2e6) !important;
     34  box-shadow: inset calc(-1 * var(--gf-phone-border-width, 1px)) 0 0 var(--gf-phone-border-color, #dee2e6) !important;
    3435  border-top-right-radius: 0 !important;
    3536  border-bottom-right-radius: 0 !important;
     
    4041  max-width: 35%;
    4142  min-width: 140px;
     43  max-width: 220px;
    4244}
    4345
     
    4648  max-width: 28%;
    4749  min-width: 120px;
     50  max-width: 180px;
    4851}
    4952
     
    5255  max-width: 16%;
    5356  min-width: 76px;
     57  max-width: 110px;
    5458}
    5559
  • griffinforms-form-builder/trunk/admin/html/formcontrols/richtext.php

    r3299683 r3456321  
    55class RichText extends \GriffinForms\Admin\Html\FormControls\Format
    66{
     7    protected function isMessageEditor()
     8    {
     9        return in_array($this->name, array('content', 'message_content'), true);
     10    }
     11
     12    protected function messageEditorSettings()
     13    {
     14        return array(
     15            // Keep TinyMCE from dropping code-mode HTML when switching tabs.
     16            'verify_html' => false,
     17            'cleanup' => false,
     18            'valid_elements' => '*[*]',
     19            'extended_valid_elements' => '*[*]',
     20            'custom_elements' => '*[*]',
     21            'valid_children' => '+*[*]',
     22        );
     23    }
     24
    725    public function html()
    826    {
     
    1129            'teeny' => true,
    1230        );
     31
     32        if ($this->isMessageEditor()) {
     33            $settings['wpautop'] = false;
     34            $settings['tinymce'] = $this->messageEditorSettings();
     35        }
     36
    1337        \wp_editor($this->value, $this->elementId(), $settings);
    1438    }
  • griffinforms-form-builder/trunk/admin/js/app/overrides.js

    r3450618 r3456321  
    7777  }
    7878
     79  function buildChevronDataUri(strokeColor) {
     80    var safeColor = strokeColor || '#6c757d';
     81    var svg = "<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><polyline points='2,4 6,8 10,4' fill='none' stroke='" + safeColor + "' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/></svg>";
     82    return 'url("data:image/svg+xml,' + encodeURIComponent(svg) + '")';
     83  }
     84
    7985  function stylePhoneInputGroup(group) {
    8086    var groupObj = jq(group);
     
    8995
    9096    var styles = window.getComputedStyle(input[0]);
     97    if (countrySelect.length) {
     98      countrySelect[0].style.setProperty('color', styles.color, 'important');
     99      countrySelect[0].style.setProperty('--gf-phone-caret-image', buildChevronDataUri(styles.color));
     100    }
    91101    var inputIndex = children.index(input);
    92102    var firstChild = children.first();
     
    111121      };
    112122
    113       // For color property, use the most prominent border color (top/bottom are more reliable than left/right)
    114       var reliableBorderColor = styles.borderTopColor || styles.borderBottomColor || styles.borderColor;
    115 
    116123      // Apply border properties for specified sides
    117124      jq.each(sides.borders, function(i, side) {
     
    120127          var cssProp = 'border-' + side + '-' + prop.toLowerCase();
    121128          var value = styles['border' + capitalSide + prop];
    122 
    123           // Special handling for Color: use reliable border color instead of side-specific
    124           if (prop === 'Color') {
    125             value = reliableBorderColor;
    126           }
    127129
    128130          // Only apply if value is not 'none' or '0px' (skip absent borders)
     
    180182      } else {
    181183        if (countrySelect.length && firstChild[0] === countrySelect[0]) {
     184          applyBorderStyles(firstChild, {
     185            borders: ['top', 'bottom', 'left'],
     186            zeroBorders: ['right'],
     187            radius: ['left'],
     188            zeroRadius: ['right']
     189          });
    182190          firstChild[0].style.setProperty('border-top-right-radius', '0', 'important');
    183191          firstChild[0].style.setProperty('border-bottom-right-radius', '0', 'important');
     
    187195          var borderColor = styles.borderRightColor;
    188196          var fallbackColor = borderColor || styles.borderTopColor || styles.borderColor;
    189           var fallbackWidth = styles.borderTopWidth;
    190           var fallbackStyle = styles.borderTopStyle;
     197          var fallbackWidth = styles.borderBottomWidth || styles.borderTopWidth;
     198          var fallbackStyle = styles.borderBottomStyle || styles.borderTopStyle;
    191199          var useWidth = (borderWidth && parseFloat(borderWidth) > 0) ? borderWidth : fallbackWidth;
    192200          var useStyle = (borderStyle && borderStyle !== 'none') ? borderStyle : fallbackStyle;
     
    205213            firstChild[0].style.setProperty('--gf-phone-border-color', fallbackColor);
    206214            firstChild[0].style.setProperty('border-right-color', fallbackColor, 'important');
    207             firstChild[0].style.setProperty('box-shadow', 'inset -1px 0 0 ' + fallbackColor, 'important');
     215            firstChild[0].style.setProperty('box-shadow', 'inset -' + useWidth + ' 0 0 ' + fallbackColor, 'important');
    208216          }
    209217          firstChild[0].style.setProperty('border-right-width', useWidth, 'important');
  • griffinforms-form-builder/trunk/admin/secure/message.php

    r3299683 r3456321  
    77    protected function secureContent($value)
    88    {
    9         return wp_kses_post($value);
     9        if (!is_string($value)) {
     10            return '';
     11        }
     12
     13        $allowed_html = $this->getAllowedMessageHtml();
     14        $allowed_protocols = wp_allowed_protocols();
     15
     16        return wp_kses($value, $allowed_html, $allowed_protocols);
     17    }
     18
     19    /**
     20     * Allowlist for message HTML content used in outgoing emails.
     21     *
     22     * Intentionally scoped to common email-safe tags/attributes.
     23     */
     24    protected function getAllowedMessageHtml()
     25    {
     26        $allowed = array(
     27            'a' => array(
     28                'href' => true,
     29                'target' => true,
     30                'rel' => true,
     31                'title' => true,
     32                'class' => true,
     33                'style' => true,
     34            ),
     35            'strong' => array(),
     36            'em' => array(),
     37            'b' => array(),
     38            'i' => array(),
     39            'u' => array(),
     40            'h1' => array(
     41                'class' => true,
     42                'style' => true,
     43            ),
     44            'h2' => array(
     45                'class' => true,
     46                'style' => true,
     47            ),
     48            'h3' => array(
     49                'class' => true,
     50                'style' => true,
     51            ),
     52            'h4' => array(
     53                'class' => true,
     54                'style' => true,
     55            ),
     56            'h5' => array(
     57                'class' => true,
     58                'style' => true,
     59            ),
     60            'h6' => array(
     61                'class' => true,
     62                'style' => true,
     63            ),
     64            'p' => array(
     65                'class' => true,
     66                'style' => true,
     67            ),
     68            'br' => array(),
     69            'ul' => array(
     70                'class' => true,
     71                'style' => true,
     72            ),
     73            'ol' => array(
     74                'class' => true,
     75                'style' => true,
     76            ),
     77            'li' => array(
     78                'class' => true,
     79                'style' => true,
     80            ),
     81            'table' => array(
     82                'class' => true,
     83                'style' => true,
     84                'border' => true,
     85                'cellpadding' => true,
     86                'cellspacing' => true,
     87                'width' => true,
     88            ),
     89            'thead' => array(
     90                'class' => true,
     91                'style' => true,
     92            ),
     93            'tbody' => array(
     94                'class' => true,
     95                'style' => true,
     96            ),
     97            'tr' => array(
     98                'class' => true,
     99                'style' => true,
     100            ),
     101            'th' => array(
     102                'class' => true,
     103                'style' => true,
     104                'colspan' => true,
     105                'rowspan' => true,
     106                'width' => true,
     107                'align' => true,
     108                'valign' => true,
     109            ),
     110            'td' => array(
     111                'class' => true,
     112                'style' => true,
     113                'colspan' => true,
     114                'rowspan' => true,
     115                'width' => true,
     116                'align' => true,
     117                'valign' => true,
     118            ),
     119            'span' => array(
     120                'class' => true,
     121                'style' => true,
     122            ),
     123            'div' => array(
     124                'class' => true,
     125                'style' => true,
     126            ),
     127        );
     128
     129        return apply_filters('griffinforms_message_allowed_html', $allowed);
    10130    }
    11131}
  • griffinforms-form-builder/trunk/blocks/gutenberg/editor.css

    r3450618 r3456321  
    174174    -webkit-appearance: none !important;
    175175    -moz-appearance: none !important;
    176     background-image: none !important;
     176    background-image: var(--gf-phone-caret-image, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpolyline points='2,4 6,8 10,4' fill='none' stroke='%236c757d' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")) !important;
     177    background-position: calc(100% - 14px) 50% !important;
     178    background-size: 12px 12px !important;
    177179    background-repeat: no-repeat !important;
    178180    white-space: nowrap !important;
    179181    overflow: hidden !important;
    180182    text-overflow: ellipsis !important;
    181     padding-right: 14px !important;
     183    padding-right: 44px !important;
    182184}
    183185
     
    203205}
    204206
     207.griffinforms-block-editor .griffinforms-block-preview.gf-xs .gf-bp-phone-group .gf-bp-phone-select.gf-bp-control[data-gf-phone-display-mode="code_only"],
     208.griffinforms-block-editor .griffinforms-block-preview.gf-sm .gf-bp-phone-group .gf-bp-phone-select.gf-bp-control[data-gf-phone-display-mode="code_only"] {
     209    background-image: none !important;
     210    padding-right: 12px !important;
     211}
    205212
    206213.griffinforms-block-editor .griffinforms-block-preview .gf-bp-textarea {
  • griffinforms-form-builder/trunk/blocks/gutenberg/overrides.js

    r3439965 r3456321  
    4949    }
    5050
     51    function buildChevronDataUri(strokeColor) {
     52        const safeColor = strokeColor || '#6c757d';
     53        const svg = "<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><polyline points='2,4 6,8 10,4' fill='none' stroke='" + safeColor + "' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/></svg>";
     54        return 'url("data:image/svg+xml,' + encodeURIComponent(svg) + '")';
     55    }
     56
    5157    function stylePhoneInputGroup(group) {
    5258        const children = Array.from(group.children);
    53         const input = group.querySelector('input, select, textarea');
     59        const input = group.querySelector('input[type="tel"]') || group.querySelector('input, select, textarea');
     60        const countrySelect = group.querySelector('select.gf-bp-phone-select');
    5461        if (!input || children.length < 2) {
    5562            return;
     
    5764
    5865        const styles = window.getComputedStyle(input);
     66        if (countrySelect) {
     67            countrySelect.style.setProperty('color', styles.color, 'important');
     68            const finalSelectColor = window.getComputedStyle(countrySelect).color;
     69            countrySelect.style.setProperty('--gf-phone-caret-image', buildChevronDataUri(finalSelectColor));
     70        }
    5971        const inputIndex = children.indexOf(input);
    6072        const firstChild = children[0];
     
    7486                right: ['border-top-right-radius', 'border-bottom-right-radius'],
    7587            };
    76             const reliableBorderColor = styles.borderTopColor || styles.borderBottomColor || styles.borderColor;
    77 
    7888            sides.borders.forEach((side) => {
    7989                const capitalSide = side.charAt(0).toUpperCase() + side.slice(1);
     
    8191                    const cssProp = 'border-' + side + '-' + prop.toLowerCase();
    8292                    let value = styles['border' + capitalSide + prop];
    83                     if (prop === 'Color') {
    84                         value = reliableBorderColor;
    85                     }
    8693                    if (value && value !== 'none' && parseFloat(value) !== 0) {
    8794                        elem.style.setProperty(cssProp, value, 'important');
  • griffinforms-form-builder/trunk/config.php

    r3455761 r3456321  
    55class Config
    66{
    7     public const VERSION = '2.3.0.0';
    8     public const DB_VER = '2.3.0.0';
     7    public const VERSION = '2.3.1.0';
     8    public const DB_VER = '2.3.1.0';
    99    public const PHP_REQUIRED = '8.2';
    1010    public const WP_REQUIRED = '6.2';
  • griffinforms-form-builder/trunk/frontend/css/gf-no-theme.css

    r3450618 r3456321  
    3333  max-width: 28% !important;
    3434  width: 28% !important;
     35  max-width: 180px !important;
    3536  white-space: nowrap;
    3637  overflow: hidden;
    3738  text-overflow: ellipsis;
    3839  background-color: rgba(0, 0, 0, 0.05) !important;
     40  padding-right: 2.25rem !important;
    3941}
    4042
     
    4446  width: 35% !important;
    4547  min-width: 140px !important;
     48  max-width: 220px !important;
    4649}
    4750
     
    5154  width: 28% !important;
    5255  min-width: 120px !important;
     56  max-width: 180px !important;
    5357}
    5458
     
    5862  width: 16% !important;
    5963  min-width: 76px !important;
     64  max-width: 110px !important;
    6065}
  • griffinforms-form-builder/trunk/frontend/css/themes/overrides.css

    r3450618 r3456321  
    6565  max-width: 35%;
    6666  min-width: 140px;
     67  max-width: 220px;
    6768}
    6869
     
    7172  max-width: 28%;
    7273  min-width: 120px;
     74  max-width: 180px;
    7375}
    7476
     
    7779  max-width: 16%;
    7880  min-width: 76px;
     81  max-width: 110px;
    7982}
    8083
    8184.griffinforms-phone-input-group .griffinforms-phone-country-select.form-select {
     85  color: inherit !important;
    8286  appearance: none !important;
    8387  -webkit-appearance: none !important;
    8488  -moz-appearance: none !important;
     89  background-image: var(--gf-phone-caret-image, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpolyline points='2,4 6,8 10,4' fill='none' stroke='%236c757d' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")) !important;
     90  background-position: calc(100% - 14px) 50% !important;
     91  background-size: 12px 12px !important;
     92  background-repeat: no-repeat !important;
     93  padding-right: 44px !important;
     94}
     95
     96.gf-xs .griffinforms-phone-input-group .griffinforms-phone-country-select.form-select[data-gf-phone-display-mode="code_only"],
     97.gf-sm .griffinforms-phone-input-group .griffinforms-phone-country-select.form-select[data-gf-phone-display-mode="code_only"] {
    8598  background-image: none !important;
    86   background-repeat: no-repeat !important;
     99  padding-right: 12px !important;
    87100}
    88101
  • griffinforms-form-builder/trunk/frontend/html/forms/traits/externalassets.php

    r3394319 r3456321  
    5656            'griffinforms-theme-' . $theme_id,
    5757            $theme_css_file,
    58             array('griffinforms-frontend'),
     58            array(),
    5959            filemtime($theme_css_path)
    6060        );
  • griffinforms-form-builder/trunk/frontend/js/themes/overrides.js

    r3449879 r3456321  
    9898});
    9999
     100jQuery(document).ready(function(jq) {
     101  function buildChevronDataUri(strokeColor) {
     102    var safeColor = strokeColor || '#6c757d';
     103    var svg = "<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><polyline points='2,4 6,8 10,4' fill='none' stroke='" + safeColor + "' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/></svg>";
     104    return 'url(\"data:image/svg+xml,' + encodeURIComponent(svg) + '\")';
     105  }
     106
     107  jq('.griffinforms-phone-input-group').each(function() {
     108    var group = jq(this);
     109    var input = group.find('input[type="tel"]').first();
     110    var select = group.find('select.griffinforms-phone-country-select').first();
     111
     112    if (!input.length || !select.length) {
     113      return;
     114    }
     115
     116    var styles = window.getComputedStyle(input[0]);
     117    select[0].style.setProperty('color', styles.color, 'important');
     118    select[0].style.setProperty('--gf-phone-caret-image', buildChevronDataUri(styles.color));
     119  });
     120});
     121
    100122/**
    101123 * Responsive class manager
     
    264286      };
    265287
    266       // For color property, use the most prominent border color (top/bottom are more reliable than left/right)
    267       var reliableBorderColor = styles.borderTopColor || styles.borderBottomColor || styles.borderColor;
    268 
    269288      // Apply border properties for specified sides
    270289      jq.each(sides.borders, function(i, side) {
     
    273292          var cssProp = 'border-' + side + '-' + prop.toLowerCase();
    274293          var value = styles['border' + capitalSide + prop];
    275 
    276           // Special handling for Color: use reliable border color instead of side-specific
    277           if (prop === 'Color') {
    278             value = reliableBorderColor;
    279           }
    280294
    281295          // Only apply if value is not 'none' or '0px' (skip absent borders)
  • griffinforms-form-builder/trunk/griffinforms.php

    r3455761 r3456321  
    44 * Plugin URI:        https://griffinforms.com/
    55 * Description:       A powerful and flexible form builder for WordPress. Create multi-page forms with drag-and-drop ease, custom validations, and full submission management.
    6  * Version:           2.3.0.0
     6 * Version:           2.3.1.0
    77 * Requires at least: 6.6
    88 * Requires PHP:      8.2
  • griffinforms-form-builder/trunk/readme.txt

    r3455761 r3456321  
    55Tested up to: 6.9
    66Requires PHP: 8.2
    7 Stable tag: 2.3.0.0
     7Stable tag: 2.3.1.0
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    174174== Changelog ==
    175175
     176= 2.3.1.0 – 2026-02-08 =
     177* Fix: Restored a clear phone country dropdown caret across frontend, form builder, and Gutenberg preview renderers.
     178* Improvement: Phone country select sizing and compact behavior refined to avoid overlap and unbalanced wide-field layouts.
     179* Fix: Phone input-group border sync now preserves asymmetric theme border styles (per-side width/style/color) across renderers.
     180* Improvement: Message editor now preserves allowlisted HTML better between Code/Visual modes.
     181* Improvement: Message save sanitization now uses a dedicated allowlist policy for email-safe HTML (including heading tags).
     182* Fix: Removed invalid frontend theme stylesheet dependency causing `WP_Styles::add` notices on newer WordPress versions.
     183
    176184= 2.3.0.0 – 2026-02-06 =
    177185* Feature: Compliance profiles (Standard, GDPR, HIPAA‑ready) with per‑form inherit/custom overrides.
     
    195203
    196204== Upgrade Notice ==
     205
     206= 2.3.1.0 =
     207Focused quality patch for phone field usability and message HTML handling. Recommended update.
    197208
    198209= 2.3.0.0 =
     
    528539== Upgrade Notice ==
    529540
     541= 2.3.1.0 =
     542Focused quality patch for phone field usability and message HTML handling. Recommended update.
     543
    530544= 2.1.9.1 =
    531545Upcoming: locale-aware country selection, improved dropdown sizing, and a clearer divider in the phone field UI.
Note: See TracChangeset for help on using the changeset viewer.