diff --git a/README.md b/README.md
index e6b48ce..1cf4747 100644
--- a/README.md
+++ b/README.md
@@ -27,10 +27,11 @@ Ready-to-Use Masks
## Exclusive PRO Features
- **Custom Masks**: Create your own masks for maximum flexibility. Tailor your forms to any requirement.
+- **Prefix and Suffix Options**: Add prefixes and suffixes to your masks for better input guidance.
+- **Minimum and Maximum Character Validation**: Ensure inputs meet your character length requirements.
+- **Inputmode Control**: Customize the input type for better usability across devices.
🚀 **Coming Soon to the PRO Version**
-- **Minimum character limits** to prevent incomplete submissions.
-- **Prefix and suffix** options for masks.
- Built-in **validation for CPF, CNPJ**, and other formats.
- And much more…
@@ -82,6 +83,10 @@ Yes, but this feature is available only in the PRO version. With the PRO version
## Changelog
```
+= 2.1 =
+* New: support to controls from version Pro.
+* Changed: code improvements.
+
= 2.0 =
* New: add inputmode to open keybord with input context. Ex.: input with tel mask will open numeric keybord.
* New: remove jQuery mask library to use our own custom library.
diff --git a/assets/css/editor.min.css b/assets/css/editor.min.css
new file mode 100644
index 0000000..1bd176a
--- /dev/null
+++ b/assets/css/editor.min.css
@@ -0,0 +1 @@
+.elementor-control.elementor-control-fme_mask_divider_control.elementor-control-type-divider>.elementor-control-content{margin-block-start:15px!important;margin-inline:0!important}a.fme-pro-feature{background:red;border-radius:4px;color:#fff;font-size:11px;padding:2px 6px}
\ No newline at end of file
diff --git a/form-masks-for-elementor.php b/form-masks-for-elementor.php
index 73d4334..6f005c5 100644
--- a/form-masks-for-elementor.php
+++ b/form-masks-for-elementor.php
@@ -5,12 +5,13 @@
* Description: Form Masks for Elementor create a custom control in field advanced tab for your customize your fields with masks. This plugin require the Elementor Pro (Form Widget).
* Author: EduardoVillao.me
* Author URI: https://eduardovillao.me/
- * Version: 2.0
+ * Version: 2.1
* Requires at least: 5.5
* Requires PHP: 7.4
* Text Domain: form-masks-for-elementor
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
+ * Requires Plugins: elementor
*/
/*
@@ -34,7 +35,7 @@
define( 'FME_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
define( 'FME_PLUGN_URL', plugin_dir_url( __FILE__ ) );
-define( 'FME_VERSION', '2.0' );
+define( 'FME_VERSION', '2.1' );
define( 'FME_PHP_MINIMUM_VERSION', '7.4' );
define( 'FME_WP_MINIMUM_VERSION', '5.5' );
@@ -51,6 +52,7 @@
} else {
include_once FME_PLUGIN_PATH . 'includes/class-fme-plugin.php';
+ FME\Includes\FME_Plugin::instance();
}
/**
diff --git a/includes/class-elementor-mask-control.php b/includes/class-elementor-mask-control.php
index 8f99126..a4fd3ef 100644
--- a/includes/class-elementor-mask-control.php
+++ b/includes/class-elementor-mask-control.php
@@ -31,33 +31,35 @@ public function __construct() {
public function add_mask_control( $element, $args ) {
$elementor = ElementorPlugin::instance();
$control_data = $elementor->controls_manager->get_control_from_stack( $element->get_name(), 'form_fields' );
+ $pro_tag = ' ' . esc_html__( 'PRO', 'form-masks-for-elementor' ) . '';
if ( is_wp_error( $control_data ) ) {
return;
}
- $new_control = [
- 'label' => __( 'Mask Control', 'form-masks-for-elementor' ),
+ $controls_to_register = [
+ 'fme_mask_control' => [
+ 'label' => esc_html__( 'Mask Control', 'form-masks-for-elementor' ),
'type' => ElementorControls::SELECT,
'tab' => 'content',
'tabs_wrapper' => 'form_fields_tabs',
'inner_tab' => 'form_fields_advanced_tab',
'default' => 'sel',
'options' => [
- 'mask' => __( 'Select Mask', 'form-masks-for-elementor' ),
- 'ev-tel' => __( 'Phone (8 dig)', 'form-masks-for-elementor' ),
- 'ev-tel-ddd' => __( 'Phone (8 dig) + DDD', 'form-masks-for-elementor' ),
- 'ev-tel-ddd9' => __( 'Phone (9 dig) + DDD', 'form-masks-for-elementor' ),
- 'ev-tel-us' => __( 'Phone USA', 'form-masks-for-elementor' ),
- 'ev-cpf' => __( 'CPF', 'form-masks-for-elementor' ),
- 'ev-cnpj' => __( 'CNPJ', 'form-masks-for-elementor' ),
- 'ev-money' => __( 'Money', 'form-masks-for-elementor' ),
- 'ev-ccard' => __( 'Credit Card', 'form-masks-for-elementor' ),
- 'ev-ccard-valid' => __( 'Credit Card Date', 'form-masks-for-elementor' ),
- 'ev-cep' => __( 'CEP', 'form-masks-for-elementor' ),
- 'ev-time' => __( 'Time', 'form-masks-for-elementor' ),
- 'ev-date' => __( 'Date', 'form-masks-for-elementor' ),
- 'ev-date_time' => __( 'Date and Time', 'form-masks-for-elementor' ),
+ 'mask' => esc_html__( 'Select Mask', 'form-masks-for-elementor' ),
+ 'ev-tel' => esc_html__( 'Phone (8 dig)', 'form-masks-for-elementor' ),
+ 'ev-tel-ddd' => esc_html__( 'Phone (8 dig) + DDD', 'form-masks-for-elementor' ),
+ 'ev-tel-ddd9' => esc_html__( 'Phone (9 dig) + DDD', 'form-masks-for-elementor' ),
+ 'ev-tel-us' => esc_html__( 'Phone USA', 'form-masks-for-elementor' ),
+ 'ev-cpf' => esc_html__( 'CPF', 'form-masks-for-elementor' ),
+ 'ev-cnpj' => esc_html__( 'CNPJ', 'form-masks-for-elementor' ),
+ 'ev-money' => esc_html__( 'Money', 'form-masks-for-elementor' ),
+ 'ev-ccard' => esc_html__( 'Credit Card', 'form-masks-for-elementor' ),
+ 'ev-ccard-valid' => esc_html__( 'Credit Card Date', 'form-masks-for-elementor' ),
+ 'ev-cep' => esc_html__( 'CEP', 'form-masks-for-elementor' ),
+ 'ev-time' => esc_html__( 'Time', 'form-masks-for-elementor' ),
+ 'ev-date' => esc_html__( 'Date', 'form-masks-for-elementor' ),
+ 'ev-date_time' => esc_html__( 'Date and Time', 'form-masks-for-elementor' ),
],
'conditions' => [
'terms' => [
@@ -68,6 +70,122 @@ public function add_mask_control( $element, $args ) {
],
],
],
+ ],
+ 'fme_mask_alert_pro_version' => [
+ 'type' => \Elementor\Controls_Manager::ALERT,
+ 'alert_type' => 'info',
+ 'content' => esc_html__( '🚀 Unlock features with the PRO version.', 'form-masks-for-elementor' ) . ' ' . esc_html__( 'Upgrade Now', 'form-masks-for-elementor' ) . '',
+ 'tab' => 'content',
+ 'tabs_wrapper' => 'form_fields_tabs',
+ 'inner_tab' => 'form_fields_advanced_tab',
+ 'conditions' => [
+ 'terms' => [
+ [
+ 'name' => 'field_type',
+ 'operator' => 'in',
+ 'value' => $this->allowed_fields,
+ ],
+ ],
+ ],
+ ],
+ 'fme_mask_prefix_control' => [
+ 'label' => esc_html__( 'Mask Prefix', 'form-masks-for-elementor' ) . $pro_tag,
+ 'type' => \Elementor\Controls_Manager::TEXT,
+ 'default' => '',
+ 'tab' => 'content',
+ 'tabs_wrapper' => 'form_fields_tabs',
+ 'inner_tab' => 'form_fields_advanced_tab',
+ 'conditions' => [
+ 'terms' => [
+ [
+ 'name' => 'field_type',
+ 'operator' => 'in',
+ 'value' => [ 'text' ],
+ ],
+ ],
+ ],
+ ],
+ 'fme_mask_suffix_control' => [
+ 'label' => esc_html__( 'Mask Suffix', 'form-masks-for-elementor' ) . $pro_tag,
+ 'type' => \Elementor\Controls_Manager::TEXT,
+ 'default' => '',
+ 'tab' => 'content',
+ 'tabs_wrapper' => 'form_fields_tabs',
+ 'inner_tab' => 'form_fields_advanced_tab',
+ 'conditions' => [
+ 'terms' => [
+ [
+ 'name' => 'field_type',
+ 'operator' => 'in',
+ 'value' => [ 'text' ],
+ ],
+ ],
+ ],
+ ],
+ 'fme_mask_reverse_control' => [
+ 'label' => esc_html__( 'Mask Reverse?', 'form-masks-for-elementor' ) . $pro_tag,
+ 'description' => esc_html__( 'Reverse mode is to format values dynamically as the user types, starting from the right (e.g., 0.01, 1.23, 12.34). Is commonly used for currency masks where the value grows from the decimal point.', 'form-masks-for-elementor' ),
+ 'type' => \Elementor\Controls_Manager::SWITCHER,
+ 'label_off' => esc_html__( 'Off', 'form-masks-for-elementor' ),
+ 'label_on' => esc_html__( 'On', 'form-masks-for-elementor' ),
+ 'return_value' => 'true',
+ 'default' => '',
+ 'tab' => 'content',
+ 'tabs_wrapper' => 'form_fields_tabs',
+ 'inner_tab' => 'form_fields_advanced_tab',
+ 'conditions' => [
+ 'terms' => [
+ [
+ 'name' => 'field_type',
+ 'operator' => 'in',
+ 'value' => [ 'text' ],
+ ],
+ ],
+ ],
+ ],
+ 'fme_mask_inputmode_control' => [
+ 'label' => esc_html__( 'Mask Input Mode', 'form-masks-for-elementor' ) . $pro_tag,
+ 'description' => esc_html__( 'Input Mode determines the type of on-screen keyboard shown to users on mobile devices.', 'form-masks-for-elementor' ),
+ 'type' => \Elementor\Controls_Manager::SELECT,
+ 'default' => 'select',
+ 'options' => [
+ 'select' => esc_html__( 'Select', 'form-masks-for-elementor' ),
+ 'text' => esc_html__( 'Text', 'form-masks-for-elementor' ),
+ 'decimal' => esc_html__( 'Decimal', 'form-masks-for-elementor' ),
+ 'numeric' => esc_html__( 'Numeric', 'form-masks-for-elementor' ),
+ 'tel' => esc_html__( 'Telephone', 'form-masks-for-elementor' ),
+ 'search' => esc_html__( 'Search', 'form-masks-for-elementor' ),
+ 'email' => esc_html__( 'Email', 'form-masks-for-elementor' ),
+ 'url' => esc_html__( 'Url', 'form-masks-for-elementor' ),
+ ],
+ 'tab' => 'content',
+ 'tabs_wrapper' => 'form_fields_tabs',
+ 'inner_tab' => 'form_fields_advanced_tab',
+ 'conditions' => [
+ 'terms' => [
+ [
+ 'name' => 'field_type',
+ 'operator' => 'in',
+ 'value' => [ 'text' ],
+ ],
+ ],
+ ],
+ ],
+ 'fme_mask_divider_control' => [
+ 'type' => \Elementor\Controls_Manager::DIVIDER,
+ 'tab' => 'content',
+ 'tabs_wrapper' => 'form_fields_tabs',
+ 'inner_tab' => 'form_fields_advanced_tab',
+ 'conditions' => [
+ 'terms' => [
+ [
+ 'name' => 'field_type',
+ 'operator' => 'in',
+ 'value' => [ 'text' ],
+ ],
+ ],
+ ],
+ ],
];
/**
@@ -75,19 +193,14 @@ public function add_mask_control( $element, $args ) {
*
* @since 1.5
*/
- $new_control = apply_filters( 'fme_after_mask_control_created', $new_control );
-
- $mask_control = new ElementorRepeater();
- $mask_control->add_control( 'fme_mask_control', $new_control );
+ $controls_to_register = apply_filters( 'fme_after_mask_control_created', $controls_to_register );
- /**
- * Action to insert more controls.
- *
- * @since 1.5.2
- */
- do_action( 'fme_after_mask_control_added', $mask_control );
+ $controls_repeater = new ElementorRepeater();
+ foreach ( $controls_to_register as $key => $control ) {
+ $controls_repeater->add_control( $key, $control );
+ }
- $pattern_field = $mask_control->get_controls();
+ $pattern_field = $controls_repeater->get_controls();
/**
* Register control in form advanced tab.
@@ -95,7 +208,6 @@ public function add_mask_control( $element, $args ) {
* @since 1.5.2
*/
$this->register_control_in_form_advanced_tab( $element, $control_data, $pattern_field );
-
}
/**
@@ -138,7 +250,7 @@ public function register_control_in_form_advanced_tab( $element, $control_data,
* @return void
*/
public function add_mask_atributes( $field, $field_index, $form_widget ) {
- if ( ! empty( $field['fme_mask_control'] ) && in_array( $field['field_type'], $this->allowed_fields ) && $field['fme_mask_control'] != 'sel' ) {
+ if ( ! empty( $field['fme_mask_control'] ) && in_array( $field['field_type'], $this->allowed_fields ) && $field['fme_mask_control'] !== 'mask' ) {
$form_widget->add_render_attribute( 'input' . $field_index, 'data-mask', $field['fme_mask_control'] );
$form_widget->add_render_attribute( 'input' . $field_index, 'class', 'fme-mask-input' );
}
diff --git a/includes/class-fme-plugin.php b/includes/class-fme-plugin.php
index 9b63aec..ce4211c 100644
--- a/includes/class-fme-plugin.php
+++ b/includes/class-fme-plugin.php
@@ -39,7 +39,6 @@ final class FME_Plugin {
* @return FME_Plugin An instance of the class.
*/
public static function instance() {
-
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
@@ -56,7 +55,6 @@ public static function instance() {
* @since 1.6
*/
public function __clone() {
- // Cloning instances of the class is forbidden.
_doing_it_wrong( __FUNCTION__, esc_html__( 'Something went wrong.', 'form-masks-for-elementor' ), '1.6' );
}
@@ -67,7 +65,6 @@ public function __clone() {
* @since 1.6
*/
public function __wakeup() {
- // Unserializing instances of the class is forbidden.
_doing_it_wrong( __FUNCTION__, esc_html__( 'Something went wrong.', 'form-masks-for-elementor' ), '1.6' );
}
@@ -81,8 +78,7 @@ public function __wakeup() {
* @access private
*/
private function __construct() {
-
- add_action( 'plugins_loaded', [ $this, 'init' ] );
+ \add_action( 'init', array( $this, 'init' ), -10 );
}
/**
@@ -95,27 +91,22 @@ private function __construct() {
* @access public
*/
public function init() {
+ if ( ! did_action( 'elementor/loaded' ) ) {
+ return;
+ }
- /**
- * Check Elementor Por is actived
- */
- if( ! $this->plugin_is_active( 'elementor-pro/elementor-pro.php' ) ) {
-
- add_action( 'admin_notices', [ $this, 'notice_elementor_pro_inactive' ] );
+ if ( ! $this->plugin_is_active( 'elementor-pro/elementor-pro.php' ) ) {
+ \add_action( 'admin_notices', array( $this, 'notice_elementor_pro_inactive' ) );
return;
}
- // action fired when plugin is activated and dependencies/requirements are checked
- do_action( 'fme_init' );
+ \do_action( 'fme_init' );
- // required files
require_once FME_PLUGIN_PATH . '/includes/class-elementor-mask-control.php';
+ new FME_Elementor_Forms_Mask();
- // instanciate mask control class
- new FME_Elementor_Forms_Mask;
-
- // register and enqueue scripts
- add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_plugin_js' ] );
+ \add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_plugin_js' ] );
+ \add_action( 'elementor/editor/after_enqueue_scripts', array( $this, 'register_editor_scripts') );
}
/**
@@ -139,6 +130,16 @@ public function enqueue_plugin_js() {
\do_action( 'fme_after_enqueue_scripts' );
}
+ /**
+ * Enqueue script on Elemento Editor
+ *
+ * @return void
+ */
+ public function register_editor_scripts() {
+ wp_register_style( 'fme-input-mask-editor', FME_PLUGN_URL . 'assets/css/editor.min.css', array(), FME_VERSION );
+ wp_enqueue_style( 'fme-input-mask-editor' );
+ }
+
/**
* Admin notice - Elementor PRO
*
@@ -149,7 +150,6 @@ public function enqueue_plugin_js() {
* @access public
*/
public function notice_elementor_pro_inactive() {
-
$message = sprintf(
esc_html__( '%1$s requires %2$s to be installed and activated.', 'form-masks-for-elementor' ),
'Form Masks for Elementor',
@@ -168,9 +168,6 @@ public function notice_elementor_pro_inactive() {
* @param string $plugin
*/
public function plugin_is_active( $plugin ) {
-
- return function_exists( 'is_plugin_active' ) ? is_plugin_active( $plugin ) : in_array( $plugin, (array) get_option( 'active_plugins', array() ), true );
+ return function_exists( 'is_plugin_active' ) ? \is_plugin_active( $plugin ) : in_array( $plugin, (array) \get_option( 'active_plugins', array() ), true );
}
}
-
-FME_Plugin::instance();
diff --git a/readme.txt b/readme.txt
index a7d4ebb..dbd87ed 100644
--- a/readme.txt
+++ b/readme.txt
@@ -4,7 +4,7 @@ Donate link: https://eduardovillao.me/
Tags: elementor, elementor form, form mask
Requires at least: 5.5
Tested up to: 6.7
-Stable tag: 2.0
+Stable tag: 2.1
Requires PHP: 7.4
License: GPLv2License
URI:https://www.gnu.org/licenses/gpl-2.0.html
@@ -40,10 +40,11 @@ Ready-to-Use Masks
**Exclusive PRO Features**
* **Custom Masks**: Create your own masks for maximum flexibility. Tailor your forms to any requirement.
+* **Prefix and Suffix Options**: Add prefixes and suffixes to your masks for better input guidance.
+* **Minimum and Maximum Character Validation**: Ensure inputs meet your character length requirements.
+* **Inputmode Control**: Customize the input type for better usability across devices.
🚀 **Coming Soon to the PRO Version**
-* **Minimum character limits** to prevent incomplete submissions.
-* **Prefix and suffix** options for masks.
* Built-in **validation for CPF, CNPJ**, and other formats.
* And much more…
@@ -97,6 +98,10 @@ Yes, but this feature is available only in the PRO version. With the PRO version
== Changelog ==
+= 2.1 =
+* New: support to controls from version Pro.
+* Changed: code improvements.
+
= 2.0 =
* New: add inputmode to open keybord with input context. Ex.: input with tel mask will open numeric keybord.
* New: remove jQuery mask library to use our own custom library.
diff --git a/src/css/editor.css b/src/css/editor.css
new file mode 100644
index 0000000..e48ded3
--- /dev/null
+++ b/src/css/editor.css
@@ -0,0 +1,12 @@
+.elementor-control.elementor-control-fme_mask_divider_control.elementor-control-type-divider > .elementor-control-content {
+ margin-inline: 0 !important;
+ margin-block-start: 15px !important;
+}
+
+a.fme-pro-feature {
+ color: #fff;
+ background: red;
+ padding: 2px 6px;
+ border-radius: 4px;
+ font-size: 11px;
+}
diff --git a/webpack.config.js b/webpack.config.js
index dae258b..612fcbf 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,5 +1,7 @@
const path = require('path');
const fs = require('fs');
+const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
+const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const srcJsGeneralDirectory = path.resolve(__dirname, 'src/js/');
const generalEntries = fs.readdirSync(srcJsGeneralDirectory).reduce((entries, file) => {
@@ -34,4 +36,29 @@ const generalJs = {
},
};
-module.exports = [generalJs];
+const editorCSS = {
+ mode: 'production',
+ entry: './src/css/editor.css',
+ output: {
+ filename: 'style.bundle.js',
+ path: path.resolve(__dirname, 'assets/css/'),
+ },
+ module: {
+ rules: [
+ {
+ test: /\.css$/,
+ use: [MiniCssExtractPlugin.loader, 'css-loader'],
+ },
+ ],
+ },
+ optimization: {
+ minimizer: [new CssMinimizerPlugin()],
+ },
+ plugins: [
+ new MiniCssExtractPlugin({
+ filename: 'editor.min.css',
+ }),
+ ],
+};
+
+module.exports = [generalJs, editorCSS];