PluginProbe
Elementor Website Builder – more than just a page builder / 3.0.3
Elementor Website Builder – more than just a page builder v3.0.3
4.3.0 4.3.0-beta3 4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 All 453 releases
← All changes | core/files/css/base.php +39 -193 4.3.0-beta23.0.3 View file →
@@ -4,16 +4,15 @@
4 4 use Elementor\Base_Data_Control;
5 5 use Elementor\Control_Repeater;
6 6 use Elementor\Controls_Manager;
7 7 use Elementor\Controls_Stack;
8 -use Elementor\Core\Breakpoints\Manager as Breakpoints_Manager;
9 8 use Elementor\Core\Files\Base as Base_File;
10 9 use Elementor\Core\DynamicTags\Manager;
11 10 use Elementor\Core\DynamicTags\Tag;
12 -use Elementor\Core\Frontend\Performance;
13 -use Elementor\Core\Frontend\Widget_Content_Render_Mode;
14 11 use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
12 +use Elementor\Element_Base;
15 13 use Elementor\Plugin;
14 +use Elementor\Core\Responsive\Responsive;
16 15 use Elementor\Stylesheet;
17 16 use Elementor\Icons_Manager;
18 17
19 18 if ( ! defined( 'ABSPATH' ) ) {
@@ -65,10 +64,8 @@
65 64 private $icons_fonts = [];
66 65
67 66 private $dynamic_elements_ids = [];
68 67
69 - private $preserved_dynamic_style_values = [];
70 -
71 68 /**
72 69 * Stylesheet object.
73 70 *
74 71 * Holds the CSS file stylesheet instance.
@@ -105,8 +102,22 @@
105 102 return false;
106 103 }
107 104
108 105 /**
106 + * CSS file constructor.
107 + *
108 + * Initializing Elementor CSS file.
109 + *
110 + * @since 1.2.0
111 + * @access public
112 + */
113 + public function __construct( $file_name ) {
114 + parent::__construct( $file_name );
115 +
116 + $this->init_stylesheet();
117 + }
118 +
119 + /**
109 120 * Use external file.
110 121 *
111 122 * Whether to use external CSS file of not. When there are new schemes or settings
112 123 * updates.
@@ -180,19 +191,8 @@
180 191 }
181 192 }
182 193
183 194 /**
184 - * Get Responsive Control Duplication Mode
185 - *
186 - * @since 3.4.0
187 - *
188 - * @return string
189 - */
190 - protected function get_responsive_control_duplication_mode() {
191 - return 'on';
192 - }
193 -
194 - /**
195 195 * Enqueue CSS.
196 196 *
197 197 * Either enqueue the CSS file in Elementor or add inline style.
198 198 *
@@ -201,12 +201,8 @@
201 201 * @since 1.2.0
202 202 * @access public
203 203 */
204 204 public function enqueue() {
205 - if ( $this->should_skip_enqueue() ) {
206 - return;
207 - }
208 -
209 205 $handle_id = $this->get_file_handle_id();
210 206
211 207 if ( isset( self::$printed[ $handle_id ] ) ) {
212 208 return;
@@ -219,17 +215,8 @@
219 215 if ( self::CSS_STATUS_EMPTY === $meta['status'] ) {
220 216 return;
221 217 }
222 218
223 - /**
224 - * Enqueue CSS file.
225 - *
226 - * Fires before enqueuing a CSS file.
227 - *
228 - * @param Base $this The current CSS file.
229 - */
230 - do_action( 'elementor/css-file/before_enqueue', $this );
231 -
232 219 // First time after clear cache and etc.
233 220 if ( '' === $meta['status'] || $this->is_update_required() ) {
234 221 $this->update();
235 222
@@ -237,17 +224,16 @@
237 224 }
238 225
239 226 if ( self::CSS_STATUS_INLINE === $meta['status'] ) {
240 227 $dep = $this->get_inline_dependency();
241 - $is_dependency_registered = (bool) wp_styles()->query( $dep, 'registered' );
242 -
243 - if ( ! $is_dependency_registered || wp_styles()->query( $dep, 'done' ) ) {
244 - printf( '<style id="%1$s">%2$s</style>', $this->get_file_handle_id(), $meta['css'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
228 + // If the dependency has already been printed ( like a template in footer )
229 + if ( wp_styles()->query( $dep, 'done' ) ) {
230 + printf( '<style id="%1$s">%2$s</style>', $this->get_file_handle_id(), $meta['css'] ); // XSS ok.
245 231 } else {
246 232 wp_add_inline_style( $dep, $meta['css'] );
247 233 }
248 234 } elseif ( self::CSS_STATUS_FILE === $meta['status'] ) { // Re-check if it's not empty after CSS update.
249 - wp_enqueue_style( $this->get_file_handle_id(), $this->get_url(), $this->get_registered_enqueue_dependencies(), null );
235 + wp_enqueue_style( $this->get_file_handle_id(), $this->get_url(), $this->get_enqueue_dependencies(), null ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion
250 236 }
251 237
252 238 // Handle fonts.
253 239 if ( ! empty( $meta['fonts'] ) ) {
@@ -279,17 +265,8 @@
279 265 *
280 266 * @param Base $this The current CSS file.
281 267 */
282 268 do_action( "elementor/css-file/{$name}/enqueue", $this );
283 -
284 - /**
285 - * Enqueue CSS file.
286 - *
287 - * Fires after enqueuing a CSS file.
288 - *
289 - * @param Base $this The current CSS file.
290 - */
291 - do_action( 'elementor/css-file/after_enqueue', $this );
292 269 }
293 270
294 271 /**
295 272 * Print CSS.
@@ -300,9 +277,9 @@
300 277 * @since 1.9.4
301 278 * @access public
302 279 */
303 280 public function print_css() {
304 - echo '<style>' . $this->get_content() . '</style>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
281 + echo '<style>' . $this->get_content() . '</style>'; // XSS ok.
305 282 Plugin::$instance->frontend->print_fonts_links();
306 283 }
307 284
308 285 /**
@@ -351,12 +328,8 @@
351 328 return;
352 329 }
353 330 }
354 331
355 - $stylesheet = $this->get_stylesheet();
356 -
357 - $control = apply_filters( 'elementor/files/css/selectors', $control, $value ?? [], $this );
358 -
359 332 foreach ( $control['selectors'] as $selector => $css_property ) {
360 333 $output_css_property = '';
361 334
362 335 if ( $global_key ) {
@@ -366,19 +339,13 @@
366 339 $output_css_property = preg_replace( '/(:)[^;]+(;?)/', '$1' . $selector_global_value . '$2', $css_property );
367 340 }
368 341 } else {
369 342 try {
370 - if ( $this->unit_has_custom_selector( $control, $value ) ) {
371 - $css_property = $control['unit_selectors_dictionary'][ $value['unit'] ];
372 - }
373 -
374 343 $output_css_property = preg_replace_callback( '/{{(?:([^.}]+)\.)?([^}| ]*)(?: *\|\| *(?:([^.}]+)\.)?([^}| ]*) *)*}}/', function( $matches ) use ( $control, $value_callback, $controls_stack, $value, $css_property ) {
375 344 $external_control_missing = $matches[1] && ! isset( $controls_stack[ $matches[1] ] );
376 345
377 346 $parsed_value = '';
378 347
379 - $value = apply_filters( 'elementor/files/css/property', $value, $css_property, $matches, $control );
380 -
381 348 if ( ! $external_control_missing ) {
382 349 $parsed_value = $this->parse_property_placeholder( $control, $value, $controls_stack, $value_callback, $matches[2], $matches[1] );
383 350 }
384 351
@@ -407,12 +374,8 @@
407 374 throw new \Exception();
408 375 }
409 376 }
410 377
411 - if ( '__EMPTY__' === $parsed_value ) {
412 - $parsed_value = '';
413 - }
414 -
415 378 return $parsed_value;
416 379 }, $css_property );
417 380 } catch ( \Exception $e ) {
418 381 return;
@@ -436,9 +399,9 @@
436 399
437 400 $pure_device_rules = $pure_device_rules[1];
438 401
439 402 foreach ( $pure_device_rules as $device_rule ) {
440 - if ( Breakpoints_Manager::BREAKPOINT_KEY_DESKTOP === $device_rule ) {
403 + if ( Element_Base::RESPONSIVE_DESKTOP === $device_rule ) {
441 404 continue;
442 405 }
443 406
444 407 $device = preg_replace( '/\+$/', '', $device_rule );
@@ -453,21 +416,17 @@
453 416
454 417 if ( ! $query && ! empty( $control['responsive'] ) ) {
455 418 $query = array_intersect_key( $control['responsive'], array_flip( [ 'min', 'max' ] ) );
456 419
457 - if ( ! empty( $query['max'] ) && Breakpoints_Manager::BREAKPOINT_KEY_DESKTOP === $query['max'] ) {
420 + if ( ! empty( $query['max'] ) && Element_Base::RESPONSIVE_DESKTOP === $query['max'] ) {
458 421 unset( $query['max'] );
459 422 }
460 423 }
461 424
462 - $stylesheet->add_rules( $parsed_selector, $output_css_property, $query );
425 + $this->stylesheet_obj->add_rules( $parsed_selector, $output_css_property, $query );
463 426 }
464 427 }
465 428
466 - protected function unit_has_custom_selector( $control, $value ) {
467 - return isset( $control['unit_selectors_dictionary'] ) && isset( $control['unit_selectors_dictionary'][ $value['unit'] ] );
468 - }
469 -
470 429 /**
471 430 * @param array $control
472 431 * @param mixed $value
473 432 * @param array $controls_stack
@@ -478,27 +437,15 @@
478 437 * @return string
479 438 */
480 439 public function parse_property_placeholder( array $control, $value, array $controls_stack, $value_callback, $placeholder, $parser_control_name = null ) {
481 440 if ( $parser_control_name ) {
482 - // If both the processed control and the control name found in the placeholder are responsive
483 - if ( ! empty( $control['responsive'] ) && ! empty( $controls_stack[ $parser_control_name ]['responsive'] ) ) {
484 - $device_suffix = Controls_Manager::get_responsive_control_device_suffix( $control );
441 + $control = $controls_stack[ $parser_control_name ];
485 442
486 - $control = $controls_stack[ $parser_control_name . $device_suffix ] ?? $controls_stack[ $parser_control_name ];
487 - } else {
488 - $control = $controls_stack[ $parser_control_name ];
489 - }
490 -
491 443 $value = call_user_func( $value_callback, $control );
492 444 }
493 445
494 - // If the control value is empty, check for global default. `0` (integer, string) are falsy but are valid values.
495 - if ( empty( $value ) && '0' !== $value && 0 !== $value ) {
496 - $value = $this->get_control_global_default_value( $control );
497 - }
498 -
499 446 if ( Controls_Manager::FONT === $control['type'] ) {
500 - $this->add_font( $value );
447 + $this->fonts[] = $value;
501 448 }
502 449
503 450 /** @var Base_Data_Control $control_obj */
504 451 $control_obj = Plugin::$instance->controls_manager->get_control( $control['type'] );
@@ -530,12 +477,8 @@
530 477 *
531 478 * @return Stylesheet The stylesheet object.
532 479 */
533 480 public function get_stylesheet() {
534 - if ( ! $this->stylesheet_obj ) {
535 - $this->init_stylesheet();
536 - }
537 -
538 481 return $this->stylesheet_obj;
539 482 }
540 483
541 484 /**
@@ -554,9 +497,9 @@
554 497 * @param array $placeholders Placeholders.
555 498 * @param array $replacements Replacements.
556 499 * @param array $all_controls All controls.
557 500 */
558 - public function add_controls_stack_style_rules( Controls_Stack $controls_stack, array $controls, array $values, array $placeholders, array $replacements, ?array $all_controls = null ) {
501 + public function add_controls_stack_style_rules( Controls_Stack $controls_stack, array $controls, array $values, array $placeholders, array $replacements, array $all_controls = null ) {
559 502 if ( ! $all_controls ) {
560 503 $all_controls = $controls_stack->get_controls();
561 504 }
562 505
@@ -578,13 +521,8 @@
578 521 if ( ! empty( $parsed_dynamic_settings[ Manager::DYNAMIC_SETTING_KEY ][ $control['name'] ] ) ) {
579 522 // Dynamic CSS should not be added to the CSS files.
580 523 // Instead it's handled by \Elementor\Core\DynamicTags\Dynamic_CSS
581 524 // and printed in a style tag.
582 - $should_preserve_value = isset( $control['control_type'] ) && 'content' === $control['control_type'];
583 - if ( $should_preserve_value ) {
584 - $this->preserved_dynamic_style_values[ $control['name'] ] = $parsed_dynamic_settings[ $control['name'] ];
585 - }
586 -
587 525 unset( $parsed_dynamic_settings[ $control['name'] ] );
588 526
589 527 $this->dynamic_elements_ids[] = $controls_stack->get_id();
590 528
@@ -611,31 +549,8 @@
611 549 * @return string CSS file handle ID.
612 550 */
613 551 abstract protected function get_file_handle_id();
614 552
615 - protected function should_skip_enqueue(): bool {
616 - if ( Widget_Content_Render_Mode::is( Widget_Content_Render_Mode::MARKDOWN ) ) {
617 - return true;
618 - }
619 -
620 - if ( ! is_admin() ) {
621 - return false;
622 - }
623 -
624 - $editor = Plugin::$instance->editor;
625 -
626 - return $editor && $editor->is_editor_request();
627 - }
628 -
629 - protected function get_registered_enqueue_dependencies(): array {
630 - return array_values( array_filter(
631 - $this->get_enqueue_dependencies(),
632 - static function ( $handle ) {
633 - return (bool) wp_styles()->query( $handle, 'registered' );
634 - }
635 - ) );
636 - }
637 -
638 553 /**
639 554 * Render CSS.
640 555 *
641 556 * Parse the CSS.
@@ -706,14 +621,8 @@
706 621 * @since 1.2.0
707 622 * @access protected
708 623 */
709 624 protected function parse_content() {
710 - Performance::set_use_style_controls( true );
711 -
712 - $initial_responsive_controls_duplication_mode = Plugin::$instance->breakpoints->get_responsive_control_duplication_mode();
713 -
714 - Plugin::$instance->breakpoints->set_responsive_control_duplication_mode( $this->get_responsive_control_duplication_mode() );
715 -
716 625 $this->render_css();
717 626
718 627 $name = $this->get_name();
719 628
@@ -729,13 +638,9 @@
729 638 * @param Base $this The current CSS file.
730 639 */
731 640 do_action( "elementor/css-file/{$name}/parse", $this );
732 641
733 - Plugin::$instance->breakpoints->set_responsive_control_duplication_mode( $initial_responsive_controls_duplication_mode );
734 -
735 - Performance::set_use_style_controls( false );
736 -
737 - return $this->get_stylesheet()->__toString();
642 + return $this->stylesheet_obj->__toString();
738 643 }
739 644
740 645 /**
741 646 * Add control style rules.
@@ -759,44 +664,8 @@
759 664 );
760 665 }
761 666
762 667 /**
763 - * Get Control Global Default Value
764 - *
765 - * If the control has a global default value, and the corresponding global default setting is enabled, this method
766 - * fetches and returns the global default value. Otherwise, it returns null.
767 - *
768 - * @since 3.7.0
769 - * @access private
770 - *
771 - * @param $control
772 - * @return string|null
773 - */
774 - private function get_control_global_default_value( $control ) {
775 - if ( empty( $control['global']['default'] ) ) {
776 - return null;
777 - }
778 -
779 - // If the control value is empty, and the control has a global default set, fetch the global value and use it.
780 - $global_enabled = false;
781 -
782 - if ( 'color' === $control['type'] ) {
783 - $global_enabled = Plugin::$instance->kits_manager->is_custom_colors_enabled();
784 - } elseif ( isset( $control['groupType'] ) && 'typography' === $control['groupType'] ) {
785 - $global_enabled = Plugin::$instance->kits_manager->is_custom_typography_enabled();
786 - }
787 -
788 - $value = null;
789 -
790 - // Only apply the global default if Global Colors are enabled.
791 - if ( $global_enabled ) {
792 - $value = $this->get_selector_global_value( $control, $control['global']['default'] );
793 - }
794 -
795 - return $value;
796 - }
797 -
798 - /**
799 668 * Get style control value.
800 669 *
801 670 * Retrieve the value of the style control for any give control and values.
802 671 *
@@ -815,11 +684,9 @@
815 684 // When the control itself has no global value, but it refers to another control global value
816 685 return $this->get_selector_global_value( $control, $values['__globals__'][ $control['name'] ] );
817 686 }
818 687
819 - $value = isset( $values[ $control['name'] ] )
820 - ? $values[ $control['name'] ]
821 - : $this->preserved_dynamic_style_values[ $control['name'] ] ?? null;
688 + $value = $values[ $control['name'] ];
822 689
823 690 if ( isset( $control['selectors_dictionary'][ $value ] ) ) {
824 691 $value = $control['selectors_dictionary'][ $value ];
825 692 }
@@ -842,13 +709,14 @@
842 709 */
843 710 private function init_stylesheet() {
844 711 $this->stylesheet_obj = new Stylesheet();
845 712
846 - $active_breakpoints = Plugin::$instance->breakpoints->get_active_breakpoints();
713 + $breakpoints = Responsive::get_breakpoints();
847 714
848 - foreach ( $active_breakpoints as $breakpoint_name => $breakpoint ) {
849 - $this->stylesheet_obj->add_device( $breakpoint_name, $breakpoint->get_value() );
850 - }
715 + $this->stylesheet_obj
716 + ->add_device( 'mobile', 0 )
717 + ->add_device( 'tablet', $breakpoints['md'] )
718 + ->add_device( 'desktop', $breakpoints['lg'] );
851 719 }
852 720
853 721 /**
854 722 * Add repeater control style rules.
@@ -902,9 +770,9 @@
902 770 } );
903 771 }
904 772
905 773 private function get_selector_global_value( $control, $global_key ) {
906 - $data = Plugin::$instance->data_manager_v2->run( $global_key );
774 + $data = Plugin::$instance->data_manager->run( $global_key );
907 775
908 776 if ( empty( $data['value'] ) ) {
909 777 return null;
910 778 }
@@ -913,18 +781,10 @@
913 781
914 782 $id = $global_args[1];
915 783
916 784 if ( ! empty( $control['groupType'] ) ) {
917 - $strings_to_replace = [ $control['groupPrefix'] ];
785 + $property_name = str_replace( [ $control['groupPrefix'], '_tablet', '_mobile' ], '', $control['name'] );
918 786
919 - $active_breakpoint_keys = array_keys( Plugin::$instance->breakpoints->get_active_breakpoints() );
920 -
921 - foreach ( $active_breakpoint_keys as $breakpoint ) {
922 - $strings_to_replace[] = '_' . $breakpoint;
923 - }
924 -
925 - $property_name = str_replace( $strings_to_replace, '', $control['name'] );
926 -
927 787 // TODO: This check won't retrieve the proper answer for array values (multiple controls).
928 788 if ( empty( $data['value'][ Global_Typography::TYPOGRAPHY_GROUP_PREFIX . $property_name ] ) ) {
929 789 return null;
930 790 }
@@ -931,16 +791,8 @@
931 791
932 792 $property_name = str_replace( '_', '-', $property_name );
933 793
934 794 $value = "var( --e-global-$control[groupType]-$id-$property_name )";
935 -
936 - if ( $control['groupPrefix'] . 'font_family' === $control['name'] ) {
937 - $default_generic_fonts = Plugin::$instance->kits_manager->get_current_settings( 'default_generic_fonts' );
938 -
939 - if ( $default_generic_fonts ) {
940 - $value .= ", $default_generic_fonts";
941 - }
942 - }
943 795 } else {
944 796 $value = "var( --e-global-$control[type]-$id )";
945 797 }
946 798
@@ -946,9 +798,9 @@
946 798
947 799 return $value;
948 800 }
949 801
950 - final protected function get_active_controls( Controls_Stack $controls_stack, ?array $controls = null, ?array $settings = null ) {
802 + final protected function get_active_controls( Controls_Stack $controls_stack, array $controls = null, array $settings = null ) {
951 803 if ( ! $controls ) {
952 804 $controls = $controls_stack->get_controls();
953 805 }
954 806
@@ -963,9 +815,9 @@
963 815 $active_controls = array_reduce(
964 816 array_keys( $controls ), function( $active_controls, $control_key ) use ( $controls_stack, $controls, $settings ) {
965 817 $control = $controls[ $control_key ];
966 818
967 - if ( $controls_stack->is_control_visible( $control, $settings, $controls ) ) {
819 + if ( $controls_stack->is_control_visible( $control, $settings ) ) {
968 820 $active_controls[ $control_key ] = $control;
969 821 }
970 822
971 823 return $active_controls;
@@ -974,9 +826,9 @@
974 826
975 827 return $active_controls;
976 828 }
977 829
978 - final public function get_style_controls( Controls_Stack $controls_stack, ?array $controls = null, ?array $settings = null ) {
830 + final public function get_style_controls( Controls_Stack $controls_stack, array $controls = null, array $settings = null ) {
979 831 $controls = $this->get_active_controls( $controls_stack, $controls, $settings );
980 832
981 833 $style_controls = [];
982 834
@@ -1053,12 +905,6 @@
1053 905
1054 906 $globals = $controls_stack->get_settings( '__globals__' );
1055 907
1056 908 return ! empty( $globals[ $control_global_key ] );
1057 - }
1058 -
1059 - public function add_font( $font ) {
1060 - if ( ! in_array( $font, $this->fonts, true ) ) {
1061 - $this->fonts[] = $font;
1062 - }
1063 909 }
1064 910 }