PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.2
Elementor Website Builder – more than just a page builder v4.3.2
4.3.2 4.3.1 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 All 455 releases
elementor / modules / atomic-widgets / elements / atomic-background-video / atomic-background-video.php

atomic-background-video.php in Elementor Website Builder – more than just a page builder 4.3.2, at modules/atomic-widgets/elements/atomic-background-video/atomic-background-video.php

349 lines 12.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Elementor\Modules\AtomicWidgets\Elements\Atomic_Background_Video;
4
5 use Elementor\Modules\AtomicWidgets\ChildrenDependencies\Child_Dependency;
6 use Elementor\Modules\AtomicWidgets\Controls\Section;
7 use Elementor\Modules\AtomicWidgets\Controls\Types\Html_Tag_Control;
8 use Elementor\Modules\AtomicWidgets\Controls\Types\Number_Control;
9 use Elementor\Modules\AtomicWidgets\Controls\Types\Switch_Control;
10 use Elementor\Modules\AtomicWidgets\Controls\Types\Text_Control;
11 use Elementor\Modules\AtomicWidgets\Controls\Types\Toggle_Control;
12 use Elementor\Modules\AtomicWidgets\Controls\Types\Video_Control;
13 use Elementor\Modules\AtomicWidgets\DynamicTags\Dynamic_Prop_Type;
14 use Elementor\Modules\AtomicWidgets\Elements\Atomic_Background_Video\Atomic_Background_Video_Content\Atomic_Background_Video_Content;
15 use Elementor\Modules\AtomicWidgets\Elements\Atomic_Background_Video\Atomic_Background_Video_Controls\Atomic_Background_Video_Controls;
16 use Elementor\Modules\AtomicWidgets\Elements\Atomic_Background_Video\Atomic_Background_Video_Pause\Atomic_Background_Video_Pause;
17 use Elementor\Modules\AtomicWidgets\Elements\Atomic_Background_Video\Atomic_Background_Video_Play\Atomic_Background_Video_Play;
18 use Elementor\Modules\AtomicWidgets\Elements\Base\Atomic_Element_Base;
19 use Elementor\Modules\AtomicWidgets\Elements\Base\Element_Builder;
20 use Elementor\Modules\AtomicWidgets\Elements\Base\Has_Element_Template;
21 use Elementor\Modules\AtomicWidgets\Elements\Base\Html_Tag_Computer;
22 use Elementor\Modules\AtomicWidgets\Elements\Loader\Frontend_Assets_Loader;
23 use Elementor\Modules\AtomicWidgets\PropDependencies\Manager as Dependency_Manager;
24 use Elementor\Modules\AtomicWidgets\PropTypes\Attributes_Prop_Type;
25 use Elementor\Modules\AtomicWidgets\PropTypes\Classes_Prop_Type;
26 use Elementor\Modules\AtomicWidgets\PropTypes\Primitives\Boolean_Prop_Type;
27 use Elementor\Modules\AtomicWidgets\PropTypes\Primitives\Number_Prop_Type;
28 use Elementor\Modules\AtomicWidgets\PropTypes\Primitives\String_Prop_Type;
29 use Elementor\Modules\AtomicWidgets\PropTypes\Size_Prop_Type;
30 use Elementor\Modules\AtomicWidgets\PropTypes\Video_Src_Prop_Type;
31 use Elementor\Modules\AtomicWidgets\Styles\Style_Definition;
32 use Elementor\Modules\AtomicWidgets\Styles\Style_Variant;
33 use Elementor\Modules\AtomicWidgets\Utils\Element_Position;
34 use Elementor\Modules\Components\PropTypes\Overridable_Prop_Type;
35 use Elementor\Plugin;
36 use Elementor\Utils;
37
38 if ( ! defined( 'ABSPATH' ) ) {
39 exit;
40 }
41
42 class Atomic_Background_Video extends Atomic_Element_Base {
43 use Has_Element_Template;
44
45 const BASE_STYLE_KEY = 'base';
46 const ELEMENT_TYPE_CONTENT = 'e-background-video-content';
47 const ELEMENT_TYPE_CONTROLS = 'e-background-video-controls';
48 const ELEMENT_TYPE_PLAY = 'e-background-video-play';
49 const ELEMENT_TYPE_PAUSE = 'e-background-video-pause';
50
51 public static $widget_description = 'Create a section with a looping video background and content layered on top. REQUIRED direct children: e-background-video-content (content area) and e-background-video-controls (play/pause controls). The controls container MUST include e-background-video-play and e-background-video-pause, each with a required e-paragraph child for the button label.';
52
53 public function __construct( $data = [], $args = null ) {
54 parent::__construct( $data, $args );
55 $this->meta( 'is_container', true );
56 }
57
58 public static function get_type() {
59 return 'e-background-video';
60 }
61
62 public static function get_element_type(): string {
63 return 'e-background-video';
64 }
65
66 public function get_title() {
67 return esc_html__( 'Background Video', 'elementor' );
68 }
69
70 public function get_keywords() {
71 return [ 'ato', 'atom', 'atoms', 'atomic', 'video', 'background', 'bg', 'media', 'autoplay', 'hero', 'film', 'mp4' ];
72 }
73
74 public function get_icon() {
75 return 'eicon-background-video';
76 }
77
78 public static function get_computed_html_tag( array $settings ): string {
79 return Utils::validate_html_tag( Html_Tag_Computer::compute( $settings, 'div' ) );
80 }
81
82 protected static function define_props_schema(): array {
83 // The States control is design-time only and directly tied to the controls. A prop dependency
84 // describes when the control is *shown* (the editor hides it when the dependency is not met),
85 // so show States only while Show Controls is on; the value is preserved when hidden (no reset).
86 $state_dependencies = Dependency_Manager::make()
87 ->where( [
88 'operator' => 'eq',
89 'path' => [ 'show_controls' ],
90 'value' => true,
91 'effect' => 'hide',
92 ] )
93 ->get();
94
95 return [
96 'classes' => Classes_Prop_Type::make()->default( [] ),
97 'tag' => String_Prop_Type::make()
98 ->enum( [ 'div', 'header', 'section', 'article', 'aside', 'footer', 'main', 'nav' ] )
99 ->default( 'div' )
100 ->description( 'The HTML tag for the background video container. Could be div, header, section, article, aside, footer, main, or nav.' ),
101 'source' => Video_Src_Prop_Type::make()->alias( 'video', 'src' ),
102 'start_time' => Number_Prop_Type::make()
103 ->default( null )
104 ->meta( Dynamic_Prop_Type::ignore() )
105 ->meta( 'suffix', 'SEC' ),
106 'end_time' => Number_Prop_Type::make()
107 ->default( null )
108 ->meta( 'suffix', 'SEC' )
109 ->meta( Dynamic_Prop_Type::ignore() ),
110 'autoplay' => Boolean_Prop_Type::make()->default( true ),
111 'mute' => Boolean_Prop_Type::make()->default( true ),
112 'loop' => Boolean_Prop_Type::make()->default( true ),
113 'show_controls' => Boolean_Prop_Type::make()->default( true ),
114 'state' => String_Prop_Type::make()
115 ->enum( [ 'playing', 'paused' ] )
116 ->default( 'playing' )
117 ->set_dependencies( $state_dependencies )
118 ->meta( Overridable_Prop_Type::ignore() ),
119 'attributes' => Attributes_Prop_Type::make()->meta( Overridable_Prop_Type::ignore() ),
120 ];
121 }
122
123 protected function define_atomic_controls(): array {
124 return [
125 Section::make()
126 ->set_label( __( 'Content', 'elementor' ) )
127 ->set_id( 'content' )
128 ->set_items( [
129 Video_Control::bind_to( 'source' )
130 ->set_label( esc_html__( 'Video', 'elementor' ) ),
131 Number_Control::bind_to( 'start_time' )
132 ->set_label( esc_html__( 'Start Time', 'elementor' ) )
133 ->set_min( 0 )
134 ->set_max( 10000 ),
135 Number_Control::bind_to( 'end_time' )
136 ->set_label( esc_html__( 'End Time', 'elementor' ) )
137 ->set_min( 0 )
138 ->set_max( 10000 ),
139 Switch_Control::bind_to( 'autoplay' )
140 ->set_label( esc_html__( 'Autoplay', 'elementor' ) ),
141 Switch_Control::bind_to( 'mute' )
142 ->set_label( esc_html__( 'Mute', 'elementor' ) ),
143 Switch_Control::bind_to( 'loop' )
144 ->set_label( esc_html__( 'Loop', 'elementor' ) ),
145 Switch_Control::bind_to( 'show_controls' )
146 ->set_label( esc_html__( 'Show Controls', 'elementor' ) ),
147 Toggle_Control::bind_to( 'state' )
148 ->set_label( esc_html__( 'States', 'elementor' ) )
149 ->add_options( [
150 'playing' => [ 'title' => esc_html__( 'Play', 'elementor' ) ],
151 'paused' => [ 'title' => esc_html__( 'Pause', 'elementor' ) ],
152 ] )
153 ->set_exclusive( true )
154 ->set_allow_empty( true )
155 ->set_convert_options( true )
156 ->set_size( 'tiny' )
157 ->set_full_width( true ),
158 ] ),
159 Section::make()
160 ->set_label( __( 'Settings', 'elementor' ) )
161 ->set_id( 'settings' )
162 ->set_items( [
163 Html_Tag_Control::bind_to( 'tag' )
164 ->set_options( [
165 [
166 'value' => 'div',
167 'label' => 'Div',
168 ],
169 [
170 'value' => 'header',
171 'label' => 'Header',
172 ],
173 [
174 'value' => 'section',
175 'label' => 'Section',
176 ],
177 [
178 'value' => 'article',
179 'label' => 'Article',
180 ],
181 [
182 'value' => 'aside',
183 'label' => 'Aside',
184 ],
185 [
186 'value' => 'footer',
187 'label' => 'Footer',
188 ],
189 [
190 'value' => 'main',
191 'label' => 'Main',
192 ],
193 [
194 'value' => 'nav',
195 'label' => 'Nav',
196 ],
197 ] )
198 ->set_label( esc_html__( 'HTML Tag', 'elementor' ) ),
199 Text_Control::bind_to( '_cssid' )
200 ->set_label( __( 'ID', 'elementor' ) )
201 ->set_meta( $this->get_css_id_control_meta() ),
202 ] ),
203 ];
204 }
205
206 protected function define_base_styles(): array {
207 return [
208 static::BASE_STYLE_KEY => Style_Definition::make()
209 ->add_variant(
210 Style_Variant::make()
211 ->add_props( [
212 'display' => String_Prop_Type::generate( 'flex' ),
213 'flex-direction' => String_Prop_Type::generate( 'column' ),
214 'position' => String_Prop_Type::generate( 'relative' ),
215 'overflow' => String_Prop_Type::generate( 'hidden' ),
216 // Match Flexbox/container default padding so the empty-state outline and
217 // stacking gaps match other layout elements. Absolute video still covers
218 // the full padding box (abspos containing block = padding edge).
219 'padding' => Size_Prop_Type::generate( [
220 'size' => 10,
221 'unit' => 'px',
222 ] ),
223 'width' => Size_Prop_Type::generate( [
224 'size' => 100,
225 'unit' => '%',
226 ] ),
227 ] )
228 ),
229 ];
230 }
231
232 protected function define_default_children() {
233 $content = Atomic_Background_Video_Content::generate()
234 ->meta( [ 'required' => true ] )
235 ->editor_settings( [
236 'title' => esc_html__( 'Content Area', 'elementor' ),
237 ] )
238 ->build();
239
240 $controls = Atomic_Background_Video_Controls::generate()
241 ->meta( [ 'required' => true ] )
242 ->editor_settings( [
243 'title' => esc_html__( 'Controls', 'elementor' ),
244 ] )
245 ->children( [
246 Atomic_Background_Video_Play::build_default_element( true ),
247 Atomic_Background_Video_Pause::build_default_element( true ),
248 ] )
249 ->build();
250
251 return [
252 $content,
253 $controls,
254 ];
255 }
256
257 protected function define_children_dependencies(): array {
258 return [
259 Child_Dependency::for( self::ELEMENT_TYPE_CONTROLS )
260 ->when(
261 Dependency_Manager::make()->where( [
262 'operator' => 'ne',
263 'path' => [ 'show_controls' ],
264 'value' => false,
265 ] )
266 )
267 ->position( Element_Position::last() )
268 ->stash( true )
269 ->default_model(
270 Element_Builder::make( self::ELEMENT_TYPE_CONTROLS )
271 ->is_locked( true )
272 ->hydrate_default_children( true )
273 ->children( [
274 Element_Builder::make( self::ELEMENT_TYPE_PLAY )
275 ->hydrate_default_children( true )
276 ->build(),
277 Element_Builder::make( self::ELEMENT_TYPE_PAUSE )
278 ->hydrate_default_children( true )
279 ->build(),
280 ] )
281 ->build()
282 ),
283 ];
284 }
285
286 protected function define_allowed_child_types() {
287 return [
288 self::ELEMENT_TYPE_CONTENT,
289 self::ELEMENT_TYPE_CONTROLS,
290 ];
291 }
292
293 public function get_script_depends() {
294 $global_depends = parent::get_script_depends();
295
296 if ( Plugin::$instance->preview->is_preview_mode() ) {
297 return array_merge( $global_depends, [ 'elementor-background-video-handler', 'elementor-background-video-preview-handler' ] );
298 }
299
300 return array_merge( $global_depends, [ 'elementor-background-video-handler' ] );
301 }
302
303 public function register_frontend_handlers() {
304 $assets_url = ELEMENTOR_ASSETS_URL;
305 $min_suffix = ( Utils::is_script_debug() || Utils::is_elementor_tests() ) ? '' : '.min';
306
307 wp_register_script(
308 'elementor-background-video-handler',
309 "{$assets_url}js/background-video-handler{$min_suffix}.js",
310 [ Frontend_Assets_Loader::FRONTEND_HANDLERS_HANDLE, Frontend_Assets_Loader::ALPINEJS_HANDLE ],
311 ELEMENTOR_VERSION,
312 true
313 );
314
315 wp_register_script(
316 'elementor-background-video-preview-handler',
317 "{$assets_url}js/background-video-preview-handler{$min_suffix}.js",
318 [ Frontend_Assets_Loader::FRONTEND_HANDLERS_HANDLE, Frontend_Assets_Loader::ALPINEJS_HANDLE ],
319 ELEMENTOR_VERSION,
320 true
321 );
322 }
323
324 protected function build_template_context(): array {
325 $settings = $this->get_atomic_settings();
326 $video_start_time = $settings['start_time'] ?? null;
327 $video_end_time = $settings['end_time'] ?? null;
328 $video_timings = '#t=0';
329
330 if ( ! empty( $video_start_time ) ) {
331 $video_timings = '#t=' . $video_start_time;
332 }
333
334 if ( ! empty( $video_end_time ) && $video_end_time > ( $video_start_time ?? 0 ) ) {
335 $video_timings .= ',' . $video_end_time;
336 }
337
338 return array_merge( $this->build_base_template_context(), [
339 'video_timings' => $video_timings,
340 ] );
341 }
342
343 protected function get_templates(): array {
344 return [
345 'elementor/elements/atomic-background-video' => __DIR__ . '/atomic-background-video.html.twig',
346 ];
347 }
348 }
349