JezK
Edit File: css-file.php
<?php namespace JET_SM\Elementor; use JET_SM\Plugin; use \Elementor\Controls_Stack; use \Elementor\Element_Base; use \Elementor\Core\DynamicTags\Manager; use \Elementor\Controls_Manager; // If this file is called directly, abort. if ( ! defined( 'WPINC' ) ) { die; } /** * Define CSS_File class */ class CSS_File extends \Elementor\Core\Files\CSS\Base { private $parent_file; private $stack; /** * CSS file constructor. * * Initializing Elementor CSS file. * * @since 1.2.0 * @access public */ public function __construct( $stack = null, $parent_file = null ) { $this->stack = $stack; $this->parent_file = $parent_file; parent::__construct( $this->get_file_name() ); } /** * Set up parent CSS file */ public function set_parent( $file = null ) { $this->parent_file = $file; } /** * Returns fil name * @return [type] [description] */ public function get_file_name() { if ( $this->parent_file ) { return $this->parent_file->get_file_name(); } else { return $this->get_file_handle_id(); } } /** * Add controls-stack style rules. * * Parse the CSS for all the elements inside any given controls stack. * * This method recursively renders the CSS for all the child elements in the stack. * * @since 1.6.0 * @access public * * @param Controls_Stack $controls_stack The controls stack. * @param array $controls Controls array. * @param array $values Values array. * @param array $placeholders Placeholders. * @param array $replacements Replacements. * @param array $all_controls All controls. */ public function add_controls_stack_style_rules( Controls_Stack $controls_stack, array $controls, array $values, array $placeholders, array $replacements, array $all_controls = null) { if ( ! $all_controls ) { $all_controls = $controls_stack->get_controls(); } $parsed_dynamic_settings = $controls_stack->parse_dynamic_settings( $values, $controls ); foreach ( $controls as $control ) { if ( ! $this->is_control_should_processed( $control ) ) { continue; } if ( ! empty( $control['style_fields'] ) ) { $this->add_repeater_control_style_rules( $controls_stack, $control, $values[ $control['name'] ], $placeholders, $replacements ); } if ( ! empty( $control[ Manager::DYNAMIC_SETTING_KEY ][ $control['name'] ] ) ) { $this->add_dynamic_control_style_rules( $control, $control[ Manager::DYNAMIC_SETTING_KEY ][ $control['name'] ] ); } if ( Controls_Manager::ICONS === $control['type'] ) { $this->icons_fonts[] = $values[ $control['name'] ]['library']; } if ( ! empty( $parsed_dynamic_settings[ Manager::DYNAMIC_SETTING_KEY ][ $control['name'] ] ) ) { unset( $parsed_dynamic_settings[ $control['name'] ] ); continue; } if ( empty( $control['selectors'] ) ) { continue; } $this->add_control_style_rules( $control, $parsed_dynamic_settings, $all_controls, $placeholders, $replacements ); } if ( $controls_stack instanceof Element_Base ) { foreach ( $controls_stack->get_children() as $ch_element ) { $element_settings = $ch_element->get_settings(); Plugin::instance()->skins->add_skin_to_rendered( $ch_element ); $this->add_controls_stack_style_rules( $ch_element, $this->get_style_controls( $ch_element ), $element_settings, array( '{{ID}}', '{{WRAPPER}}' ), array( $ch_element->get_id(), $this->get_element_unique_selector( $ch_element ) ) ); } } } /** * Returns unique selector name for the element * * @param [type] $element [description] * @return [type] [description] */ public function get_element_unique_selector( $element ) { if ( $this->parent_file ) { return $this->parent_file->get_element_unique_selector( $element ); } else { return '.elementor .elementor-inner .elementor-element' . $element->get_unique_selector(); } } /** * Add control rules. * * Parse the CSS for all the elements inside any given control. * * This method recursively renders the CSS for all the selectors in the control. * * @since 1.2.0 * @access public * * @param array $control The controls. * @param array $controls_stack The controls stack. * @param callable $value_callback Callback function for the value. * @param array $placeholders Placeholders. * @param array $replacements Replacements. */ public function add_control_rules( array $control, array $controls_stack, callable $value_callback, array $placeholders, array $replacements, array $values = [] ) { $value = call_user_func( $value_callback, $control ); if ( null === $value || empty( $control['selectors'] ) ) { return; } foreach ( $control['selectors'] as $selector => $css_property ) { try { $output_css_property = preg_replace_callback( '/\{\{(?:([^.}]+)\.)?([^}| ]*)(?: *\|\| *(?:([^.}]+)\.)?([^}| ]*) *)*}}/', function( $matches ) use ( $control, $value_callback, $controls_stack, $value, $css_property ) { $external_control_missing = $matches[1] && ! isset( $controls_stack[ $matches[1] ] ); $parsed_value = ''; if ( ! $external_control_missing ) { $parsed_value = $this->parse_property_placeholder( $control, $value, $controls_stack, $value_callback, $matches[2], $matches[1] ); } if ( '' === $parsed_value ) { if ( isset( $matches[4] ) ) { $parsed_value = $matches[4]; $is_string_value = preg_match( '/^([\'"])(.*)\1$/', $parsed_value, $string_matches ); if ( $is_string_value ) { $parsed_value = $string_matches[2]; } elseif ( ! is_numeric( $parsed_value ) ) { if ( $matches[3] && ! isset( $controls_stack[ $matches[3] ] ) ) { return ''; } $parsed_value = $this->parse_property_placeholder( $control, $value, $controls_stack, $value_callback, $matches[4], $matches[3] ); } } if ( '' === $parsed_value ) { if ( $external_control_missing ) { return ''; } throw new \Exception(); } } return $parsed_value; }, $css_property ); } catch ( \Exception $e ) { return; } if ( ! $output_css_property ) { continue; } $device_pattern = '/^(?:\([^\)]+\)){1,2}/'; preg_match( $device_pattern, $selector, $device_rules ); $query = []; if ( $device_rules ) { $selector = preg_replace( $device_pattern, '', $selector ); preg_match_all( '/\(([^\)]+)\)/', $device_rules[0], $pure_device_rules ); $pure_device_rules = $pure_device_rules[1]; foreach ( $pure_device_rules as $device_rule ) { if ( Element_Base::RESPONSIVE_DESKTOP === $device_rule ) { continue; } $device = preg_replace( '/\+$/', '', $device_rule ); $endpoint = $device === $device_rule ? 'max' : 'min'; $query[ $endpoint ] = $device; } } $parsed_selector = str_replace( $placeholders, $replacements, $selector ); if ( ! $query && ! empty( $control['responsive'] ) ) { $query = array_intersect_key( $control['responsive'], array_flip( [ 'min', 'max' ] ) ); if ( ! empty( $query['max'] ) && Element_Base::RESPONSIVE_DESKTOP === $query['max'] ) { unset( $query['max'] ); } } $level = absint( $control['visible_on_level'] ); $plugin = $control['jet_plugin']; $this->stack->add_to_stack( $this->get_post_id(), $level, $plugin, array( 'parsed_selector' => $parsed_selector, 'output_css_property' => $output_css_property, 'query' => $query, ) ); } } /** * Check if current control should be processed by style manager * * @param [type] $control [description] * @return boolean [description] */ public function is_control_should_processed( $control ) { if ( ! isset( $control['visible_on_level'] ) ) { return false; } if ( ! isset( $control['jet_plugin'] ) ) { return false; } if ( ! Plugin::instance()->compatibility->is_plugin_supported( $control['jet_plugin'] ) ) { return false; } return true; } /** * Returns post ID * Fallback to compatibility with Post_CSS instance. * * @return [type] [description] */ public function get_post_id() { if ( $this->parent_file ) { return $this->parent_file->get_post_id(); } else { return false; } } /** * Get CSS file name. * * Retrieve the CSS file name. * * @since 1.6.0 * @access public * * @return string CSS file name. */ public function get_name() { return 'css-stack'; } /** * Get file handle ID. * * Retrieve the handle ID for the post CSS file. * * @since 1.2.0 * @access protected * * @return string CSS file handle ID. */ protected function get_file_handle_id() { return 'css-stack'; } /** * Render CSS. * * Parse the CSS for all the elements. * * @since 1.2.0 * @access protected */ protected function render_css() {} }