Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhance: form builder content body UI redesign #1491

Open
wants to merge 13 commits into
base: develop
Choose a base branch
from
51 changes: 49 additions & 2 deletions Gruntfile.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
'use strict';
module.exports = function(grunt) {
module.exports = function( grunt) {
const tailwindFileMap = {
'admin/form-builder/views/form-builder.php': 'admin/form-builder.css',
}

var formBuilderAssets = require('./admin/form-builder/assets/js/form-builder-assets.js');

var pkg = grunt.file.readJSON('package.json');
Expand Down Expand Up @@ -112,7 +116,20 @@ module.exports = function(grunt) {
tasks: [
'shell:npm_build'
]
}
},

tailwind: {
files: [
'src/css/**/*.css',
'admin/form-builder/views/*.php',
'includes/Admin/views/*.php',
'admin/form-builder/assets/js/**/*'
],
tasks: ['shell:tailwind'],
options: {
spawn: false
}
},
},

// Clean up build directory
Expand Down Expand Up @@ -221,6 +238,11 @@ module.exports = function(grunt) {
shell: {
npm_build: {
command: 'npm run build',
},
tailwind: {
command: function ( input, output ) {
return `npx tailwindcss -i ${input} -o ${output}`;
}
Comment on lines +242 to +245
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance the Tailwind shell command with error handling and build modes.

Consider these improvements:

  1. Add error handling for the shell command
  2. Add production mode for minification
  3. Validate input/output paths
 shell: {
     tailwind: {
         command: function ( input, output ) {
-            return `npx tailwindcss -i ${input} -o ${output}`;
+            if (!input || !output) {
+                grunt.fail.warn('Input and output paths are required');
+            }
+            const mode = grunt.option('production') ? '--minify' : '';
+            return `npx tailwindcss -i ${input} -o ${output} ${mode} || exit 1`;
         }
     }
 }

Committable suggestion was skipped due to low confidence.

}
}
});
Expand All @@ -238,6 +260,7 @@ module.exports = function(grunt) {
grunt.loadNpmTasks( 'grunt-notify' );
grunt.loadNpmTasks( 'grunt-wp-readme-to-markdown' );
grunt.loadNpmTasks( 'grunt-shell' );
grunt.loadNpmTasks( 'grunt-postcss' );

grunt.registerTask( 'default', [ 'less', 'concat', 'uglify', 'i18n' ] );

Expand All @@ -248,4 +271,28 @@ module.exports = function(grunt) {
// build stuff
grunt.registerTask( 'release', [ 'less', 'concat', 'uglify', 'i18n', 'readme' ] );
grunt.registerTask( 'zip', [ 'clean', 'copy', 'compress' ] );

grunt.event.on('watch', function(action, filepath, target) {
if (target === 'tailwind') {
grunt.task.run('tailwind');
}
});
Comment on lines +275 to +279
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Optimize watch handler to process only changed files.

The current implementation runs the full Tailwind task for any file change. Consider processing only the affected files by using the filepath parameter.

 grunt.event.on('watch', function(action, filepath, target) {
     if (target === 'tailwind') {
-        grunt.task.run('tailwind');
+        // Find the corresponding CSS file for the changed PHP file
+        const cssFile = Object.entries(tailwindFileMap).find(([phpFile]) => 
+            filepath.includes(phpFile)
+        )?.[1];
+        
+        if (cssFile) {
+            const inputFile = `src/css/${cssFile}`;
+            const outputFile = `assets/css/${cssFile}`;
+            grunt.task.run(`shell:tailwind:${inputFile}:${outputFile}`);
+        } else if (filepath.endsWith('.css')) {
+            // Process CSS file changes directly
+            const match = filepath.match(/src\/css\/(.+)$/);
+            if (match) {
+                const outputFile = `assets/css/${match[1]}`;
+                grunt.task.run(`shell:tailwind:${filepath}:${outputFile}`);
+            }
+        }
     }
 });

Committable suggestion was skipped due to low confidence.


grunt.registerTask('tailwind', function() {
const done = this.async();

// Process each file mapping
Object.entries(tailwindFileMap).forEach(([phpFile, cssFile]) => {
const inputFile = `src/css/${cssFile}`;
const outputFile = `assets/css/${cssFile}`;

// Ensure the input file exists
if (grunt.file.exists(inputFile)) {
// Run the tailwind command
grunt.task.run(`shell:tailwind:${inputFile}:${outputFile}`);
}
});

done();
});
Comment on lines +281 to +297
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance Tailwind task with better error handling and feedback.

The task could benefit from:

  1. Error handling for missing files
  2. Progress feedback
  3. Parallel processing for better performance
 grunt.registerTask('tailwind', function() {
     const done = this.async();
+    let hasErrors = false;
+    const promises = [];
 
     // Process each file mapping
     Object.entries(tailwindFileMap).forEach(([phpFile, cssFile]) => {
         const inputFile = `src/css/${cssFile}`;
         const outputFile = `assets/css/${cssFile}`;
 
         // Ensure the input file exists
         if (grunt.file.exists(inputFile)) {
-            // Run the tailwind command
-            grunt.task.run(`shell:tailwind:${inputFile}:${outputFile}`);
+            grunt.log.writeln(`Processing ${inputFile} → ${outputFile}`);
+            promises.push(new Promise((resolve, reject) => {
+                grunt.util.spawn({
+                    cmd: 'npx',
+                    args: ['tailwindcss', '-i', inputFile, '-o', outputFile]
+                }, (error, result, code) => {
+                    if (error) {
+                        grunt.log.error(`Error processing ${inputFile}: ${error}`);
+                        hasErrors = true;
+                        reject(error);
+                    } else {
+                        grunt.log.ok(`Successfully processed ${outputFile}`);
+                        resolve();
+                    }
+                });
+            }));
+        } else {
+            grunt.log.error(`Input file ${inputFile} not found`);
+            hasErrors = true;
         }
     });
 
-    done();
+    Promise.all(promises)
+        .then(() => {
+            if (hasErrors) {
+                done(false);
+            } else {
+                grunt.log.ok('Tailwind processing completed successfully');
+                done();
+            }
+        })
+        .catch(() => done(false));
 });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
grunt.registerTask('tailwind', function() {
const done = this.async();
// Process each file mapping
Object.entries(tailwindFileMap).forEach(([phpFile, cssFile]) => {
const inputFile = `src/css/${cssFile}`;
const outputFile = `assets/css/${cssFile}`;
// Ensure the input file exists
if (grunt.file.exists(inputFile)) {
// Run the tailwind command
grunt.task.run(`shell:tailwind:${inputFile}:${outputFile}`);
}
});
done();
});
grunt.registerTask('tailwind', function() {
const done = this.async();
let hasErrors = false;
const promises = [];
// Process each file mapping
Object.entries(tailwindFileMap).forEach(([phpFile, cssFile]) => {
const inputFile = `src/css/${cssFile}`;
const outputFile = `assets/css/${cssFile}`;
// Ensure the input file exists
if (grunt.file.exists(inputFile)) {
grunt.log.writeln(`Processing ${inputFile}${outputFile}`);
promises.push(new Promise((resolve, reject) => {
grunt.util.spawn({
cmd: 'npx',
args: ['tailwindcss', '-i', inputFile, '-o', outputFile]
}, (error, result, code) => {
if (error) {
grunt.log.error(`Error processing ${inputFile}: ${error}`);
hasErrors = true;
reject(error);
} else {
grunt.log.ok(`Successfully processed ${outputFile}`);
resolve();
}
});
}));
} else {
grunt.log.error(`Input file ${inputFile} not found`);
hasErrors = true;
}
});
Promise.all(promises)
.then(() => {
if (hasErrors) {
done(false);
} else {
grunt.log.ok('Tailwind processing completed successfully');
done();
}
})
.catch(() => done(false));
});

};
105 changes: 61 additions & 44 deletions admin/form-builder/assets/js/components/builder-stage/template.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div id="form-preview-stage" class="wpuf-style">
<div id="form-preview-stage">
<h4 v-if="!form_fields.length" class="text-center">
<?php _e( 'Add fields by dragging the fields from the right sidebar to this area.', 'wp-user-frontend' ); ?>
</h4>
Expand All @@ -7,72 +7,89 @@
<li
v-for="(field, index) in form_fields"
:key="field.id"
:class="[
'field-items', 'wpuf-el', field.name, field.css, 'form-field-' + field.template,
field.width ? 'field-size-' + field.width : '',
('custom_hidden_field' === field.template) ? 'hidden-field' : '',
parseInt(editing_form_id) === parseInt(field.id) ? 'current-editing' : ''
]"
:data-index="index"
data-source="stage"
>
<div v-if="!is_full_width(field.template)" class="wpuf-label">
<label v-if="!is_invisible(field)" :for="'wpuf-' + field.name ? field.name : 'cls'">
:class="[
'field-items', 'wpuf-el', field.name, field.css, 'form-field-' + field.template,
field.width ? 'field-size-' + field.width : '',
('custom_hidden_field' === field.template) ? 'hidden-field' : '',
parseInt(editing_form_id) === parseInt(field.id) ? 'current-editing' : '',
index === 0 ? '' : 'wpuf-mt-4'
]"
class="wpuf-group wpuf-relative wpuf-flex wpuf-justify-between wpuf-rounded-lg wpuf-bg-white wpuf-p-4 wpuf-border wpuf-border-transparent wpuf-transition wpuf-duration-150 wpuf-ease-out">
<div v-if="!(is_full_width(field.template) || is_pro_feature(field.template))" class="wpuf-w-1/4">
<label
v-if="!is_invisible(field)"
:for="'wpuf-' + field.name ? field.name : 'cls'"
class="wpuf-block wpuf-text-sm wpuf-font-medium wpuf-leading-6 wpuf-text-gray-900">
{{ field.label }} <span v-if="field.required && 'yes' === field.required" class="required">*</span>
</label>
</div>

<component v-if="is_template_available(field)" :is="'form-' + field.template" :field="field"></component>

<div v-if="is_pro_feature(field.template)" class="stage-pro-alert">
<label class="wpuf-pro-text-alert">
<a :href="pro_link" target="_blank"><strong>{{ get_field_name(field.template) }}</strong> <?php _e( 'is available in Pro Version', 'wp-user-frontend' ); ?></a>
</label>
<div :class="(is_full_width(field.template) || is_pro_feature(field.template)) ? 'wpuf-w-full' : 'wpuf-w-3/4'">
<component v-if="is_template_available(field)" :is="'form-' + field.template" :field="field"></component>
<div v-if="is_pro_feature(field.template)" class="stage-pro-alert wpuf-text-center">
<label class="wpuf-pro-text-alert">
<a :href="pro_link" target="_blank" class="wpuf-text-gray-700 wpuf-text-base"><strong>{{ get_field_name(field.template) }}</strong> <?php _e( 'is available in Pro Version', 'wp-user-frontend' ); ?></a>
</label>
</div>
</div>

<div class="control-buttons">
<p>
<div class="control-buttons wpuf-opacity-0 group-hover:wpuf-opacity-100 control-buttons wpuf-rounded-lg wpuf-absolute wpuf-w-full wpuf-h-full wpuf-bg-gray-50/50 wpuf-top-0 wpuf-left-0 wpuf-flex wpuf-justify-around wpuf-items-center wpuf-shadow-sm wpuf-bg-gray-100/50 wpuf-ease-in wpuf-border wpuf-border-dashed wpuf-border-gray-300">
<p class="wpuf-flex">
<template v-if="!is_failed_to_validate(field.template)">
<i class="fa fa-arrows move"></i>
<i class="fa fa-pencil" @click="open_field_settings(field.id)"></i>
<i class="fa fa-clone" @click="clone_field(field.id, index)"></i>
<i
:class="action_button_classes"
class="fa fa-arrows move wpuf-rounded-l-md hover:!wpuf-cursor-move"></i>
<i
:class="action_button_classes"
class="fa fa-pencil" @click="open_field_settings(field.id)"></i>
<i
:class="action_button_classes"
class="fa fa-clone" @click="clone_field(field.id, index)"></i>
</template>
<template v-else>
<i class="fa fa-arrows control-button-disabled"></i>
<i class="fa fa-pencil control-button-disabled"></i>
<i class="fa fa-clone control-button-disabled"></i>
<i
:class="action_button_classes"
class="fa fa-arrows control-button-disabled wpuf--ml-1 wpuf-rounded-l-md"></i>
<i
:class="action_button_classes"
class="fa fa-pencil control-button-disabled wpuf--ml-1"></i>
<i
:class="action_button_classes"
class="fa fa-clone control-button-disabled wpuf--ml-1"></i>
</template>
<i class="fa fa-trash-o" @click="delete_field(index)"></i>
<i
:class="!is_pro_feature(field.template) ? [action_button_classes, 'wpuf-rounded-r-md'] : action_button_classes"
class="fa fa-trash-o wpuf--ml-1" @click="delete_field(index)"></i>
<a
v-if="is_pro_feature(field.template)"
:href="pro_link"
target="_blank"
class="wpuf-p-2 wpuf-bg-slate-800 wpuf-rounded-r-md hover:wpuf-bg-slate-500 hover:wpuf-cursor-pointer wpuf-transition wpuf-duration-150 wpuf-ease-out hover:wpuf-transition-all">
<svg
width="15" height="15" viewBox="0 0 20 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.2131 4.11564C19.2161 4.16916 19.2121 4.22364 19.1983 4.27775L17.9646 10.5323C17.9024 10.7741 17.6796 10.9441 17.4235 10.9455L10.0216 10.9818H10.0188H2.61682C2.35933 10.9818 2.13495 10.8112 2.07275 10.5681L0.839103 4.29542C0.824897 4.23985 0.820785 4.18385 0.824374 4.12895C0.34714 3.98269 0 3.54829 0 3.03636C0 2.40473 0.528224 1.89091 1.17757 1.89091C1.82692 1.89091 2.35514 2.40473 2.35514 3.03636C2.35514 3.39207 2.18759 3.71033 1.92523 3.92058L3.46976 5.43433C3.86011 5.81695 4.40179 6.03629 4.95596 6.03629C5.61122 6.03629 6.23596 5.7336 6.62938 5.22647L9.1677 1.95491C8.95447 1.74764 8.82243 1.46124 8.82243 1.14545C8.82243 0.513818 9.35065 0 10 0C10.6493 0 11.1776 0.513818 11.1776 1.14545C11.1776 1.45178 11.0526 1.72982 10.8505 1.93556L10.8526 1.93811L13.3726 5.21869C13.7658 5.73069 14.3928 6.03636 15.0499 6.03636C15.6092 6.03636 16.1351 5.82451 16.5305 5.43978L18.0848 3.92793C17.8169 3.71775 17.6449 3.39644 17.6449 3.03636C17.6449 2.40473 18.1731 1.89091 18.8224 1.89091C19.4718 1.89091 20 2.40473 20 3.03636C20 3.53462 19.6707 3.9584 19.2131 4.11564ZM17.8443 12.6909C17.8443 12.3897 17.5932 12.1455 17.2835 12.1455H2.77884C2.46916 12.1455 2.21809 12.3897 2.21809 12.6909V14C2.21809 14.3012 2.46916 14.5455 2.77884 14.5455H17.2835C17.5932 14.5455 17.8443 14.3012 17.8443 14V12.6909Z" fill="#FB9A28"/>
</svg>
</a>
</p>
</div>
</li>
</ul>

<li v-if="!form_fields.length" class="field-items empty-list-item"></li>

<li class="wpuf-submit">
<div class="wpuf-label">&nbsp;</div>
<li class="wpuf-submit wpuf-list-none">
<div class="wpuf-label">&nbsp;</div>

<?php do_action( 'wpuf_form_builder_template_builder_stage_submit_area' ); ?>
</li>
</ul><!-- .wpuf-form -->
<?php do_action( 'wpuf_form_builder_template_builder_stage_submit_area' ); ?>
</li>

<div v-if="hidden_fields.length" class="hidden-field-list">
<div v-if="hidden_fields.length" class="wpuf-border-t wpuf-border-dashed wpuf-border-gray-300">
<h4><?php esc_html_e( 'Hidden Fields', 'wp-user-frontend' ); ?></h4>

<ul class="wpuf-form">
<li
v-for="(field, index) in hidden_fields"
:class="['field-items', parseInt(editing_form_id) === parseInt(field.id) ? 'current-editing' : '']"
:class="['field-items wpuf-bg-gray-50 hover:wpuf-bg-gray-100', parseInt(editing_form_id) === parseInt(field.id) ? 'current-editing' : '']"
>
<strong><?php esc_html_e( 'key', 'wp-user-frontend' ); ?></strong>: {{ field.name }} | <strong><?php esc_html_e( 'value', 'wp-user-frontend' ); ?></strong>: {{ field.meta_value }}

<div class="control-buttons">
<p>
<i class="fa fa-pencil" @click="open_field_settings(field.id)"></i>
<i class="fa fa-clone" @click="clone_field(field.id, index)"></i>
<i class="fa fa-trash-o" @click="delete_hidden_field(field.id)"></i>
</p>
</div>
</li>
</ul>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,38 @@
<div class="wpuf-fields">
<ul :class="['wpuf-fields-list', ('yes' === field.inline) ? 'wpuf-list-inline' : '']">
<li v-if="has_options" v-for="(label, val) in field.options">
<label>
<div
v-if="field.inline !== 'yes'"
class="wpuf-space-y-2">
<div
v-if="has_options" v-for="(label, val) in field.options"
class="wpuf-relative wpuf-flex wpuf-items-center">
<div class="wpuf-flex wpuf-items-center">
<input
type="checkbox"
:value="val"
:checked="is_selected(val)"
:class="class_names('checkbox_btns')"
> {{ label }}
</label>
</li>
</ul>
class="wpuf-h-4 wpuf-w-4 wpuf-rounded wpuf-border-gray-300 wpuf-text-indigo-600 focus:wpuf-ring-indigo-600 !wpuf-mt-0.5">
<label class="wpuf-ml-3 wpuf-text-sm wpuf-font-medium wpuf-text-gray-900">{{ label }}</label>
</div>
</div>
</div>

<span v-if="field.help" class="wpuf-help" v-html="field.help" />
<div
v-else
class="wpuf-flex"
>
<div
v-if="has_options" v-for="(label, val) in field.options"
class="wpuf-relative wpuf-flex wpuf-items-center wpuf-mr-4">
<input
type="checkbox"
:value="val"
:checked="is_selected(val)"
:class="class_names('checkbox_btns')"
class="!wpuf-mt-[.5px] wpuf-rounded wpuf-border-gray-300 wpuf-text-indigo-600">
<label class="wpuf-ml-1 wpuf-text-sm wpuf-font-medium wpuf-text-gray-900">{{ label }}</label>
</div>
</div>
Comment on lines +20 to +35
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using a more robust alignment approach.

While the current alignment works, the !wpuf-mt-[.5px] is quite precise and might not be consistent across different browsers or font sizes.

Consider using flexbox alignment instead:

-class="!wpuf-mt-[.5px] wpuf-rounded wpuf-border-gray-300 wpuf-text-indigo-600"
+class="wpuf-self-center wpuf-rounded wpuf-border-gray-300 wpuf-text-indigo-600"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div
v-else
class="wpuf-flex"
>
<div
v-if="has_options" v-for="(label, val) in field.options"
class="wpuf-relative wpuf-flex wpuf-items-center wpuf-mr-4">
<input
type="checkbox"
:value="val"
:checked="is_selected(val)"
:class="class_names('checkbox_btns')"
class="!wpuf-mt-[.5px] wpuf-rounded wpuf-border-gray-300 wpuf-text-indigo-600">
<label class="wpuf-ml-1 wpuf-text-sm wpuf-font-medium wpuf-text-gray-900">{{ label }}</label>
</div>
</div>
<div
v-else
class="wpuf-flex"
>
<div
v-if="has_options" v-for="(label, val) in field.options"
class="wpuf-relative wpuf-flex wpuf-items-center wpuf-mr-4">
<input
type="checkbox"
:value="val"
:checked="is_selected(val)"
:class="class_names('checkbox_btns')"
class="wpuf-self-center wpuf-rounded wpuf-border-gray-300 wpuf-text-indigo-600">
<label class="wpuf-ml-1 wpuf-text-sm wpuf-font-medium wpuf-text-gray-900">{{ label }}</label>
</div>
</div>


<p v-if="field.help" class="wpuf-mt-2 wpuf-text-sm wpuf-text-gray-500" v-html="field.help"></p>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Based on the search results, I can now provide a complete analysis of how the help text is handled:

  1. In the form builder Vue templates, the help text is output using v-html without sanitization:
<p v-if="field.help" class="wpuf-mt-2 wpuf-text-sm wpuf-text-gray-500" v-html="field.help"></p>
  1. In the PHP backend, when rendering forms, the help text is sanitized in two places:

a. In Field_Contract.php:

<span class="wpuf-help"><?php echo stripslashes( $field['help'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></span>

b. In Render_Form.php:

<span class="wpuf-help"><?php echo esc_html( stripslashes( $attr['help'] ) ); ?></span>

The issue is that while the PHP backend properly sanitizes the help text using esc_html(), the Vue form builder templates use v-html which renders HTML content without sanitization, making it vulnerable to XSS attacks.

Final Response:

Help text needs sanitization in form builder templates to prevent XSS

The help text is currently rendered using v-html in form builder templates without sanitization, which could allow XSS attacks. While the PHP backend properly sanitizes help text using esc_html(), this protection is bypassed in the form builder interface.

  • Replace v-html="field.help" with v-text="field.help" in all form builder templates to prevent HTML injection
  • Alternatively, implement a Vue filter to sanitize HTML before rendering
🔗 Analysis chain

Verify help text sanitization for XSS prevention.

The use of v-html for help text could be vulnerable to XSS attacks if the content isn't properly sanitized.

Let's check how the help text is processed:


Let me search for how the help text content is processed before being displayed. Let's look for where the field help text is set or sanitized.


Let me search for where the help text content is set or processed before being displayed in the form builder.


Let me search for where the help text is processed before being displayed and any sanitization that might be applied.


Let me try a different search pattern to find how the help text is processed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for help text sanitization in the codebase
rg -A 5 "field\.help" --type php

Length of output: 23289


Script:

#!/bin/bash
# Search for field help text initialization or sanitization
rg -A 5 "field\['help'\]|field\.help\s*=" --type js --type php

# Also search for any sanitization functions that might be used
rg -A 5 "sanitize|escape" --type js --type php

Length of output: 362504


Script:

#!/bin/bash
# Search for where field help text is set or processed in form builder
ast-grep --pattern 'field.help = $_' 
ast-grep --pattern 'field["help"] = $_'

# Also search for form builder initialization code
rg -A 5 "form_builder|form-builder" --type js

Length of output: 37896


Script:

#!/bin/bash
# Search for help text processing in PHP files
rg -A 5 "help.*=.*field\[.*help" --type php
rg -A 5 "sanitize.*help" --type php

# Search for help text in Vue components
ast-grep --pattern 'v-html="$_"'

Length of output: 118


Script:

#!/bin/bash
# Search for help text processing in PHP files
rg -A 5 "help.*text" --type php
rg -A 5 "field\[.?'help" --type php

# Search for help text in Vue templates
rg -A 5 'v-html.*help' --type php --type vue --type html

Length of output: 66456

</div>
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<div v-bind:class="['wpuf-field-columns', 'has-columns-'+field.columns]">
<div v-bind:class="['wpuf-field-columns wpuf-bg-gray-50 wpuf-min-h-20', 'has-columns-'+field.columns]">
<div class="wpuf-column-field-inner-columns">
<div class="wpuf-column">
<div class="wpuf-column wpuf-flex">
<!-- don't change column class names -->
<div v-for="column in columnClasses" :class="[column, 'items-of-column-'+field.columns, 'wpuf-column-inner-fields']" :style="{ width: field.inner_columns_size[column], paddingRight: field.column_space+'px'}">
<div v-for="column in columnClasses" :class="[column, 'items-of-column-'+field.columns, 'wpuf-column-inner-fields wpuf-pattern-1 wpuf-min-h-16 wpuf-m-2']" :style="{ width: field.inner_columns_size[column], paddingRight: field.column_space+'px'}">
<ul class="wpuf-column-fields-sortable-list">
<li
v-for="(field, index) in column_fields[column]"
Expand Down Expand Up @@ -44,4 +44,4 @@
</div>
</div>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<div class="wpuf-fields">
<input
type="text"
:class="class_names('textfield')"
:class="builder_class_names('text_hidden')"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Based on the findings, I can now generate the final response:

The change to builder_class_names('text_hidden') needs adjustment

The builder_class_names method in the form-field mixin doesn't handle the 'text_hidden' type in its switch statement. The current implementation only handles specific types like 'text', 'url', 'email', 'textareafield', 'textfield', 'select', and 'upload_btn'.

  • The method will still return an array with:
    • type_class ('text_hidden')
    • required class (if applicable)
    • field-specific class ('wpuf_[field.name]_[form_id]')
    • commonClasses (empty string in this case)
  • Consider adding a case for 'text_hidden' in the switch statement if specific styling is needed
🔗 Analysis chain

Verify the builder_class_names implementation.

The change to builder_class_names('text_hidden') appears to be part of a standardized approach to class management.

Let's verify the implementation of this new method:


Let me gather more information about the class naming methods to better understand the implementation.


Let me search for any Vue-related files or mixins that might define these class naming methods.


Let me check the implementation of the builder_class_names method in the form-field mixin to understand its functionality.


Let me check one more thing to see how the text_hidden type is handled in the builder_class_names method.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the builder_class_names implementation and its usage
ast-grep --pattern 'builder_class_names'

# Also check for any potential references to the old class naming
rg "class_names\('textfield'\)"

Length of output: 482


Script:

#!/bin/bash
# Search for class_names and builder_class_names method definitions
ast-grep --pattern 'function class_names'
ast-grep --pattern 'function builder_class_names'
ast-grep --pattern 'const class_names'
ast-grep --pattern 'const builder_class_names'

# Search for any imports or mixins that might define these methods
rg -A 3 "import.*class.*names"
rg -A 3 "mixin.*class.*names"

Length of output: 44699


Script:

#!/bin/bash
# Search for Vue-related files that might contain class naming methods
fd -e vue -e js | xargs rg -l "class.*names"

# Search for any Vue mixins
fd -e vue -e js | xargs rg -l "mixins.*class.*names"

# Search for builder_class_names in JS files
rg -A 5 "builder_class_names" --type js

Length of output: 1408


Script:

#!/bin/bash
# Get the full implementation of builder_class_names from the form-field mixin
rg -A 20 "builder_class_names: function\(type_class\)" "admin/form-builder/assets/js/mixins/form-field.js"

# Also check if there are any other files using this method
rg "\builder_class_names\(" --type js

Length of output: 1207


Script:

#!/bin/bash
# Get more context around the builder_class_names implementation
rg -A 30 "builder_class_names: function\(type_class\)" "admin/form-builder/assets/js/mixins/form-field.js"

# Also check for any text_hidden related code
rg "case 'text_hidden':" --type js
rg "text_hidden" --type js

Length of output: 1512

:placeholder="field.placeholder"
:value="field.default"
:size="field.size"
>
<span v-if="field.help" class="wpuf-help" v-html="field.help" />
<p v-if="field.help" class="wpuf-mt-2 wpuf-text-sm wpuf-text-gray-500" v-html="field.help"></p>
</div>
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
<div class="wpuf-fields">
<select
:class="class_names('select_lbl')"
>
class="wpuf-block wpuf-w-full wpuf-min-w-full wpuf-rounded-md wpuf-py-1.5 wpuf-text-gray-900 wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300">
<option v-if="field.first" value="">{{ field.first }}</option>

<option
v-if="has_options"
v-for="(label, val) in field.options"
:value="label"
:selected="is_selected(label)"
>{{ label }}</option>
</select>

<span v-if="field.help" class="wpuf-help" v-html="field.help"> </span>
<p v-if="field.help" class="wpuf-mt-2 wpuf-text-sm wpuf-text-gray-500" v-html="field.help"></p>
</div>
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<div class="wpuf-fields">
<input
type="email"
:class="class_names('email')"
:class="class_names('email') + builder_class_names('text')"
:placeholder="field.placeholder"
:value="field.default"
:size="field.size"
>
<span v-if="field.help" class="wpuf-help" v-html="field.help" />
<p v-if="field.help" class="wpuf-mt-2 wpuf-text-sm wpuf-text-gray-500" v-html="field.help"></p>
</div>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="wpuf-fields">
<div :id="'wpuf-img_label-' + field.id + '-upload-container'">
<div class="wpuf-attachment-upload-filelist" data-type="file" data-required="yes">
<a class="button file-selector" href="#">
<a :class="builder_class_names('upload_btn')" href="#">
<template v-if="field.button_label === ''">
<?php _e( 'Select Image', 'wp-user-frontend' ); ?>
</template>
Expand All @@ -12,5 +12,5 @@
</div>
</div>

<span v-if="field.help" class="wpuf-help" v-html="field.help" />
<p v-if="field.help" class="wpuf-mt-2 wpuf-text-sm wpuf-text-gray-500" v-html="field.help"></p>
</div>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="wpuf-fields">
<div :id="'wpuf-img_label-' + field.id + '-upload-container'">
<div class="wpuf-attachment-upload-filelist" data-type="file" data-required="yes">
<a class="button file-selector wpuf_img_label_148" href="#">
<a :class="builder_class_names('upload_btn')" href="#">
<template v-if="field.button_label === ''">
<?php _e( 'Select Image', 'wp-user-frontend' ); ?>
</template>
Expand All @@ -12,5 +12,5 @@
</div>
</div>

<span v-if="field.help" class="wpuf-help" v-html="field.help"/>
<p v-if="field.help" class="wpuf-mt-2 wpuf-text-sm wpuf-text-gray-500" v-html="field.help"></p>
</div>
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<div class="wpuf-fields">
<select
:class="class_names('multi_label')"
class="wpuf-block wpuf-w-full wpuf-min-w-full wpuf-rounded-md wpuf-py-1.5 wpuf-text-gray-900 wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300"
multiple
>
<option v-if="field.first" value="">{{ field.first }}</option>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
<textarea
v-if="'no' === field.rich"
:class="class_names('textareafield')"
class="wpuf-block wpuf-w-full wpuf-rounded-md wpuf-py-1.5 wpuf-text-gray-900 wpuf-shadow-sm placeholder:wpuf-text-gray-400 sm:wpuf-text-sm sm:wpuf-leading-6 wpuf-border !wpuf-border-gray-300"
:placeholder="field.placeholder"
:rows="field.rows"
:cols="field.cols"
>{{ field.default }}</textarea>

<text-editor v-if="'no' !== field.rich" :rich="field.rich" :default_text="field.default"></text-editor>

<span v-if="field.help" class="wpuf-help" v-html="field.help" ></span>
<p v-if="field.help" class="wpuf-mt-2 wpuf-text-sm wpuf-text-gray-500" v-html="field.help"></p>
</div>
Loading
Loading