_is_edit_mode = \Elementor\Plugin::instance()->editor->is_edit_mode(); } /** * Get widget categories. * * @return array Widget categories. */ public function get_categories() { return [ 'master-addons' ]; } /** * Whether the widget has dynamic content. * Default is false for better editor performance. * Override and return true in widgets that need dynamic content (e.g., blog, posts). * * @return bool */ protected function is_dynamic_content(): bool { return false; } /** * Normalize FA4 icon values to FA5 format. * * Converts legacy Font Awesome 4 icon arrays (e.g. 'fa fa-plus') * to Font Awesome 5 format (e.g. 'fas fa-plus') so icons render * correctly even when Elementor's "Load Font Awesome 4 Support" is disabled. * * @param array $icon Icon array with 'value' and 'library' keys. * @return array Normalized icon array. */ protected function normalize_fa_icon( $icon ) { if ( empty( $icon['value'] ) || ! is_string( $icon['value'] ) ) { return $icon; } // Only convert FA4 single-prefix format: "fa fa-xxx" if ( preg_match( '/^fa fa-(.+)$/', $icon['value'], $matches ) ) { $icon_name = $matches[1]; // FA4 outline icons (-o suffix) map to FA5 "regular" style if ( substr( $icon_name, -2 ) === '-o' ) { $icon['value'] = 'far fa-' . substr( $icon_name, 0, -2 ); $icon['library'] = 'regular'; } else { $icon['value'] = 'fas fa-' . $icon_name; $icon['library'] = 'solid'; } } return $icon; } /** * Render a Font Awesome icon with proper CSS enqueue. * * Normalizes FA4→FA5 format AND ensures the correct Font Awesome CSS * is loaded on the frontend. Without this, icons break when Elementor's * "Load Font Awesome 4 Support" setting is disabled because Elementor * only loads FA CSS globally when that shim is active. * * @param array $icon Icon array with 'value' and 'library' keys. * @param array $attributes HTML attributes for the icon element. * @param string $tag HTML tag to use (default 'i'). * @return bool Whether the icon was rendered. */ protected function render_icon( $icon, $attributes = [], $tag = 'i' ) { $icon = $this->normalize_fa_icon( $icon ); if ( empty( $icon['value'] ) || empty( $icon['library'] ) ) { return false; } // Ensure the Font Awesome CSS is enqueued for this icon's library. // wp_enqueue_style() alone is too late during render (head already printed), // so wp_print_styles() forces the tag to print inline in the body. // WordPress tracks printed handles and won't duplicate them. $fa_css_map = [ 'solid' => 'elementor-icons-fa-solid', 'fa-solid' => 'elementor-icons-fa-solid', 'regular' => 'elementor-icons-fa-regular', 'fa-regular' => 'elementor-icons-fa-regular', 'brands' => 'elementor-icons-fa-brands', 'fa-brands' => 'elementor-icons-fa-brands', ]; if ( isset( $fa_css_map[ $icon['library'] ] ) && ! $this->_is_edit_mode ) { $handle = $fa_css_map[ $icon['library'] ]; if ( ! wp_style_is( $handle, 'done' ) ) { wp_enqueue_style( $handle ); wp_print_styles( [ $handle ] ); } } return \Elementor\Icons_Manager::render_icon( $icon, $attributes, $tag ); } /** * Check if widget has inner wrapper. * Handles Elementor's optimized markup experiment. * * @return bool */ public function has_widget_inner_wrapper(): bool { return ! \Elementor\Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' ); } /** * Override from addon to add custom wrapper class. * * @return string */ protected function get_custom_wrapper_class() { return ''; } /** * Overriding default function to add custom html class. * * @return string */ public function get_html_wrapper_class() { $html_class = parent::get_html_wrapper_class(); $html_class .= ' jltma-addon'; $html_class .= ' ' . $this->get_name(); $html_class .= ' ' . $this->get_custom_wrapper_class(); return rtrim( $html_class ); } /** * Method for adding editor helper attributes * * @param string $key * @param string $name * * @return void */ public function add_helper_render_attribute( $key, $name = '' ) { if ( ! $this->_is_edit_mode ) return; $this->add_render_attribute( $key, [ 'data-jltma-helper' => $name, 'class' => 'jltma-editor-helper', ] ); } /** * Method for adding a placeholder for the widget in the preview area * * @param array $args * * @return string|void */ public function render_placeholder( $args ) { if ( ! $this->_is_edit_mode ) return ''; $defaults = [ 'title_tag' => 'h4', 'title' => $this->get_title(), 'body' => __( 'This is a placeholder for this widget and will not shown on the page.', 'master-addons' ), ]; $args = wp_parse_args( $args, $defaults ); $this->add_render_attribute([ 'jltma-placeholder' => [ 'class' => 'jltma-editor-placeholder', ], 'jltma-placeholder-title' => [ 'class' => 'jltma-editor-placeholder__title', ], 'jltma-placeholder-body' => [ 'class' => 'jltma-editor-placeholder__body', ], ]); ob_start(); ?>