PluginProbe
Elementor Website Builder – more than just a page builder / 3.11.5
Elementor Website Builder – more than just a page builder v3.11.5
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 4.1.0-dev1 4.0.7 All 451 releases
elementor / modules / lazyload / module.php

module.php in Elementor Website Builder – more than just a page builder 3.11.5, at modules/lazyload/module.php

192 lines 6.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor\Modules\LazyLoad;
3
4 use Elementor\Core\Base\Module as BaseModule;
5 use Elementor\Core\Experiments\Manager as Experiments_Manager;
6 use Elementor\Element_Base;
7 use Elementor\Utils;
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit; // Exit if accessed directly
11 }
12
13 class Module extends BaseModule {
14
15 const EXPERIMENT_NAME = 'e_lazyload';
16
17 public function get_name() {
18 return 'lazyload';
19 }
20
21 public static function get_experimental_data() {
22 return [
23 'name' => static::EXPERIMENT_NAME,
24 'title' => esc_html__( 'Lazy Load Background Images', 'elementor' ),
25 'tag' => esc_html__( 'Performance', 'elementor' ),
26 'description' => esc_html__( 'Lazy loading images that are not in the viewport improves initial page load performance and user experience. By activating this experiment all background images except the first one on your page will be lazy loaded to improve your LCP score', 'elementor' ),
27 'release_status' => Experiments_Manager::RELEASE_STATUS_ALPHA,
28 'default' => Experiments_Manager::STATE_INACTIVE,
29 ];
30 }
31
32 private function enqueue_styles() {
33 wp_enqueue_style(
34 'elementor-lazyload',
35 $this->get_css_assets_url( 'modules/lazyload/frontend' ),
36 [],
37 ELEMENTOR_VERSION
38 );
39 }
40
41 private function update_element_attributes( Element_Base $element ) {
42 $settings = $element->get_settings_for_display();
43 $controls = $element->get_controls();
44 $lazyload_attribute_name = 'data-e-bg-lazyload';
45
46 $controls_with_background_image = array_filter( $controls, function( $control ) {
47 return Utils::get_array_value_by_keys( $control, [ 'background_lazyload', 'active' ] );
48 } );
49
50 foreach ( $controls_with_background_image as $control_name => $control_data ) {
51 $keys = Utils::get_array_value_by_keys( $control_data, [ 'background_lazyload', 'keys' ] );
52 $background_image_url = Utils::get_array_value_by_keys( $settings, $keys );
53 if ( $background_image_url ) {
54
55 $has_attribute = $element->get_render_attributes( '_wrapper', $lazyload_attribute_name );
56 if ( ! $has_attribute ) {
57 $bg_selector = Utils::get_array_value_by_keys( $control_data, [ 'background_lazyload', 'selector' ] ) ?? '';
58 $element->add_render_attribute( '_wrapper', [
59 $lazyload_attribute_name => $bg_selector,
60 ] );
61 }
62 }
63 }
64 }
65
66 private function append_lazyload_selector( $control, $value ) {
67 if ( Utils::get_array_value_by_keys( $control, [ 'background_lazyload', 'active' ] ) ) {
68 foreach ( $control['selectors'] as $selector => $css_property ) {
69 if ( 0 === strpos( $css_property, 'background-image' ) ) {
70 if ( ! empty( $value['url'] ) ) {
71 $css_property = str_replace( 'url("{{URL}}")', 'var(--e-bg-lazyload-loaded)', $css_property );
72 $control['selectors'][ $selector ] = $css_property . '--e-bg-lazyload: url("' . $value['url'] . '");';
73 $control = $this->apply_dominant_color_background( $control, $value, $selector );
74 }
75 }
76 }
77 }
78 return $control;
79 }
80
81 private function apply_dominant_color_background( $control, $value, $selector ) {
82 $metadata = wp_get_attachment_metadata( $value['id'] );
83 $dominant_color = Utils::get_array_value_by_keys( $metadata, [ 'dominant_color' ] );
84 if ( $dominant_color ) {
85 $control['selectors'][ $selector ] .= "background-color: #{$dominant_color};";
86 }
87 return $control;
88 }
89
90 private function is_document_support_lazyload( $post_id ) {
91 if ( ! $post_id ) {
92 return false;
93 }
94
95 $document = \Elementor\Plugin::$instance->documents->get( $post_id );
96
97 if ( $document ) {
98 $support_lazyload = $document->get_property( 'support_lazyload' );
99 if ( false === $support_lazyload ) {
100 return false;
101 }
102 }
103
104 return true;
105 }
106
107 public function __construct() {
108 parent::__construct();
109
110 // Disable lazyload in admin area (true if inside WordPress administration interface - Editor, Admin, etc.)
111 if ( is_admin() ) {
112 return;
113 }
114
115 add_action( 'elementor/element/after_add_attributes', function( Element_Base $element ) {
116
117 $current_document = \Elementor\Plugin::$instance->documents->get_current();
118
119 if ( ! $current_document ) {
120 return;
121 }
122
123 $post_id = $current_document->get_main_id();
124
125 if ( ! $this->is_document_support_lazyload( $post_id ) ) {
126 return;
127 }
128
129 $this->update_element_attributes( $element );
130 } );
131
132 add_filter('elementor/files/css/selectors', function( $control, $value, $css_instance ) {
133
134 $post_id = method_exists( $css_instance, 'get_post_id' ) ? $css_instance->get_post_id() : false;
135
136 if ( ! $post_id ) {
137 return $control;
138 }
139
140 if ( ! $this->is_document_support_lazyload( $post_id ) ) {
141 return $control;
142 }
143
144 return $this->append_lazyload_selector( $control, $value );
145 }, 10, 3);
146
147 add_filter( 'body_class', function( $classes ) {
148 $classes[] = 'e-lazyload';
149 return $classes;
150 } );
151
152 add_action( 'wp_enqueue_scripts', function() {
153 $this->enqueue_styles();
154 } );
155
156 add_action( 'wp_footer', function() {
157 ?>
158 <script type='text/javascript'>
159 const lazyloadRunObserver = () => {
160 const dataAttribute = 'data-e-bg-lazyload';
161 const lazyloadBackgrounds = document.querySelectorAll( `[${ dataAttribute }]:not(.lazyloaded)` );
162 const lazyloadBackgroundObserver = new IntersectionObserver( ( entries ) => {
163 entries.forEach( ( entry ) => {
164 if ( entry.isIntersecting ) {
165 let lazyloadBackground = entry.target;
166 const lazyloadSelector = lazyloadBackground.getAttribute( dataAttribute );
167 if ( lazyloadSelector ) {
168 lazyloadBackground = entry.target.querySelector( lazyloadSelector );
169 }
170 lazyloadBackground.classList.add( 'lazyloaded' );
171 lazyloadBackgroundObserver.unobserve( entry.target );
172 }
173 });
174 }, { rootMargin: '100px 0px 100px 0px' } );
175 lazyloadBackgrounds.forEach( ( lazyloadBackground ) => {
176 lazyloadBackgroundObserver.observe( lazyloadBackground );
177 } );
178 };
179 const events = [
180 'DOMContentLoaded',
181 'elementor/lazyload/observe',
182 ];
183 events.forEach( ( event ) => {
184 document.addEventListener( event, lazyloadRunObserver );
185 } );
186 </script>
187 <?php
188 } );
189
190 }
191 }
192