PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.0-beta3
Elementor Website Builder – more than just a page builder v4.3.0-beta3
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 4.0.8 All 454 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.0-beta3, at modules/atomic-widgets/elements/atomic-background-video/atomic-background-video.php

341 lines 12.0 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 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' ] )
99 ->default( 'div' )
100 ->description( 'The HTML tag for the background video container. Could be div, header, section, article, aside, or footer.' ),
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 ->set_label( esc_html__( 'HTML Tag', 'elementor' ) ),
191 Text_Control::bind_to( '_cssid' )
192 ->set_label( __( 'ID', 'elementor' ) )
193 ->set_meta( $this->get_css_id_control_meta() ),
194 ] ),
195 ];
196 }
197
198 protected function define_base_styles(): array {
199 return [
200 static::BASE_STYLE_KEY => Style_Definition::make()
201 ->add_variant(
202 Style_Variant::make()
203 ->add_props( [
204 'display' => String_Prop_Type::generate( 'flex' ),
205 'flex-direction' => String_Prop_Type::generate( 'column' ),
206 'position' => String_Prop_Type::generate( 'relative' ),
207 'overflow' => String_Prop_Type::generate( 'hidden' ),
208 // Match Flexbox/container default padding so the empty-state outline and
209 // stacking gaps match other layout elements. Absolute video still covers
210 // the full padding box (abspos containing block = padding edge).
211 'padding' => Size_Prop_Type::generate( [
212 'size' => 10,
213 'unit' => 'px',
214 ] ),
215 'width' => Size_Prop_Type::generate( [
216 'size' => 100,
217 'unit' => '%',
218 ] ),
219 ] )
220 ),
221 ];
222 }
223
224 protected function define_default_children() {
225 $content = Atomic_Background_Video_Content::generate()
226 ->meta( [ 'required' => true ] )
227 ->editor_settings( [
228 'title' => esc_html__( 'Content Area', 'elementor' ),
229 ] )
230 ->build();
231
232 $controls = Atomic_Background_Video_Controls::generate()
233 ->meta( [ 'required' => true ] )
234 ->editor_settings( [
235 'title' => esc_html__( 'Controls', 'elementor' ),
236 ] )
237 ->children( [
238 Atomic_Background_Video_Play::build_default_element( true ),
239 Atomic_Background_Video_Pause::build_default_element( true ),
240 ] )
241 ->build();
242
243 return [
244 $content,
245 $controls,
246 ];
247 }
248
249 protected function define_children_dependencies(): array {
250 return [
251 Child_Dependency::for( self::ELEMENT_TYPE_CONTROLS )
252 ->when(
253 Dependency_Manager::make()->where( [
254 'operator' => 'ne',
255 'path' => [ 'show_controls' ],
256 'value' => false,
257 ] )
258 )
259 ->position( Element_Position::last() )
260 ->stash( true )
261 ->default_model(
262 Element_Builder::make( self::ELEMENT_TYPE_CONTROLS )
263 ->is_locked( true )
264 ->hydrate_default_children( true )
265 ->children( [
266 Element_Builder::make( self::ELEMENT_TYPE_PLAY )
267 ->hydrate_default_children( true )
268 ->build(),
269 Element_Builder::make( self::ELEMENT_TYPE_PAUSE )
270 ->hydrate_default_children( true )
271 ->build(),
272 ] )
273 ->build()
274 ),
275 ];
276 }
277
278 protected function define_allowed_child_types() {
279 return [
280 self::ELEMENT_TYPE_CONTENT,
281 self::ELEMENT_TYPE_CONTROLS,
282 ];
283 }
284
285 public function get_script_depends() {
286 $global_depends = parent::get_script_depends();
287
288 if ( Plugin::$instance->preview->is_preview_mode() ) {
289 return array_merge( $global_depends, [ 'elementor-background-video-handler', 'elementor-background-video-preview-handler' ] );
290 }
291
292 return array_merge( $global_depends, [ 'elementor-background-video-handler' ] );
293 }
294
295 public function register_frontend_handlers() {
296 $assets_url = ELEMENTOR_ASSETS_URL;
297 $min_suffix = ( Utils::is_script_debug() || Utils::is_elementor_tests() ) ? '' : '.min';
298
299 wp_register_script(
300 'elementor-background-video-handler',
301 "{$assets_url}js/background-video-handler{$min_suffix}.js",
302 [ Frontend_Assets_Loader::FRONTEND_HANDLERS_HANDLE, Frontend_Assets_Loader::ALPINEJS_HANDLE ],
303 ELEMENTOR_VERSION,
304 true
305 );
306
307 wp_register_script(
308 'elementor-background-video-preview-handler',
309 "{$assets_url}js/background-video-preview-handler{$min_suffix}.js",
310 [ Frontend_Assets_Loader::FRONTEND_HANDLERS_HANDLE, Frontend_Assets_Loader::ALPINEJS_HANDLE ],
311 ELEMENTOR_VERSION,
312 true
313 );
314 }
315
316 protected function build_template_context(): array {
317 $settings = $this->get_atomic_settings();
318 $video_start_time = $settings['start_time'] ?? null;
319 $video_end_time = $settings['end_time'] ?? null;
320 $video_timings = '#t=0';
321
322 if ( ! empty( $video_start_time ) ) {
323 $video_timings = '#t=' . $video_start_time;
324 }
325
326 if ( ! empty( $video_end_time ) && $video_end_time > ( $video_start_time ?? 0 ) ) {
327 $video_timings .= ',' . $video_end_time;
328 }
329
330 return array_merge( $this->build_base_template_context(), [
331 'video_timings' => $video_timings,
332 ] );
333 }
334
335 protected function get_templates(): array {
336 return [
337 'elementor/elements/atomic-background-video' => __DIR__ . '/atomic-background-video.html.twig',
338 ];
339 }
340 }
341