Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/elementor/includes/elements/container.php
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
<?php
2
+
namespace Elementor\Includes\Elements;
3
+
4
+
use Elementor\Controls_Manager;
5
+
use Elementor\Core\Breakpoints\Manager as Breakpoints_Manager;
6
+
use Elementor\Element_Base;
7
+
use Elementor\Embed;
8
+
use Elementor\Group_Control_Background;
9
+
use Elementor\Group_Control_Border;
10
+
use Elementor\Group_Control_Box_Shadow;
11
+
use Elementor\Group_Control_Css_Filter;
12
+
use Elementor\Group_Control_Flex_Container;
13
+
use Elementor\Group_Control_Flex_Item;
14
+
use Elementor\Group_Control_Grid_Container;
15
+
use Elementor\Plugin;
16
+
use Elementor\Shapes;
17
+
use Elementor\Utils;
18
+
19
+
if ( ! defined( 'ABSPATH' ) ) {
20
+
exit; // Exit if accessed directly.
21
+
}
22
+
23
+
class Container extends Element_Base {
24
+
25
+
/**
26
+
* @var \Elementor\Core\Kits\Documents\Kit
27
+
*/
28
+
private $active_kit;
29
+
30
+
protected function is_dynamic_content(): bool {
31
+
return false;
32
+
}
33
+
34
+
/**
35
+
* Container constructor.
36
+
*
37
+
* @param array $data
38
+
* @param array|null $args
39
+
*
40
+
* @return void
41
+
*/
42
+
public function __construct( array $data = [], ?array $args = null ) {
43
+
parent::__construct( $data, $args );
44
+
45
+
$this->active_kit = Plugin::$instance->kits_manager->get_active_kit();
46
+
}
47
+
48
+
/**
49
+
* Get the element type.
50
+
*
51
+
* @return string
52
+
*/
53
+
public static function get_type() {
54
+
return 'container';
55
+
}
56
+
57
+
/**
58
+
* Get the element name.
59
+
*
60
+
* @return string
61
+
*/
62
+
public function get_name() {
63
+
return 'container';
64
+
}
65
+
66
+
/**
67
+
* Get the element display name.
68
+
*
69
+
* @return string
70
+
*/
71
+
public function get_title() {
72
+
return esc_html__( 'Container', 'elementor' );
73
+
}
74
+
75
+
/**
76
+
* Get the element display icon.
77
+
*
78
+
* @return string
79
+
*/
80
+
public function get_icon() {
81
+
return 'eicon-container';
82
+
}
83
+
84
+
public function get_keywords() {
85
+
return [ 'Container', 'Flex', 'Flexbox', 'Flexbox Container', 'Grid', 'Grid Container', 'CSS Grid', 'Layout' ];
86
+
}
87
+
88
+
public function get_panel_presets() {
89
+
return [
90
+
'container_grid' => [
91
+
'replacements' => [
92
+
'name' => 'container_grid',
93
+
'controls' => [
94
+
'container_type' => [ 'default' => 'grid' ],
95
+
],
96
+
'title' => esc_html__( 'Grid', 'elementor' ),
97
+
'icon' => 'eicon-container-grid',
98
+
'custom' => [
99
+
'isPreset' => true,
100
+
'originalWidget' => $this->get_name(),
101
+
'presetWidget' => 'container_grid',
102
+
'preset_settings' => [
103
+
'container_type' => 'grid',
104
+
'presetTitle' => esc_html__( 'Grid', 'elementor' ),
105
+
'presetIcon' => 'eicon-container-grid',
106
+
],
107
+
],
108
+
],
109
+
],
110
+
];
111
+
}
112
+
113
+
/**
114
+
* Override the render attributes to add a custom wrapper class.
115
+
*
116
+
* @return void
117
+
*/
118
+
protected function add_render_attributes() {
119
+
parent::add_render_attributes();
120
+
121
+
$is_nested_class_name = $this->get_data( 'isInner' ) ? 'e-child' : 'e-parent';
122
+
123
+
$this->add_render_attribute( '_wrapper', [
124
+
'class' => [
125
+
'e-con',
126
+
$is_nested_class_name,
127
+
],
128
+
] );
129
+
}
130
+
131
+
/**
132
+
* Override the initial element config to display the Container in the panel.
133
+
*
134
+
* @return array
135
+
*/
136
+
protected function get_initial_config() {
137
+
$config = parent::get_initial_config();
138
+
139
+
$config['controls'] = $this->get_controls();
140
+
$config['tabs_controls'] = $this->get_tabs_controls();
141
+
$config['show_in_panel'] = true;
142
+
$config['categories'] = [ 'layout' ];
143
+
$config['include_in_widgets_config'] = true;
144
+
145
+
return $config;
146
+
}
147
+
148
+
/**
149
+
* Render the element JS template.
150
+
*
151
+
* @return void
152
+
*/
153
+
protected function content_template() {
154
+
?>
155
+
<# if ( 'boxed' === settings.content_width ) { #>
156
+
<div class="e-con-inner">
157
+
<#
158
+
}
159
+
if ( settings.background_video_link ) {
160
+
let videoAttributes = 'autoplay muted playsinline';
161
+
162
+
if ( ! settings.background_play_once ) {
163
+
videoAttributes += ' loop';
164
+
}
165
+
166
+
view.addRenderAttribute(
167
+
'background-video-container',
168
+
{
169
+
'class': 'elementor-background-video-container',
170
+
'aria-hidden': 'true',
171
+
}
172
+
);
173
+
174
+
if ( ! settings.background_play_on_mobile ) {
175
+
view.addRenderAttribute( 'background-video-container', 'class', 'elementor-hidden-mobile' );
176
+
}
177
+
#>
178
+
<div {{{ view.getRenderAttributeString( 'background-video-container' ) }}}>
179
+
<div class="elementor-background-video-embed"></div>
180
+
<video class="elementor-background-video-hosted" {{ videoAttributes }}></video>
181
+
</div>
182
+
<# } #>
183
+
<div class="elementor-shape elementor-shape-top" aria-hidden="true"></div>
184
+
<div class="elementor-shape elementor-shape-bottom" aria-hidden="true"></div>
185
+
<# if ( 'boxed' === settings.content_width ) { #>
186
+
</div>
187
+
<# } #>
188
+
<?php
189
+
}
190
+
191
+
/**
192
+
* Render the video background markup.
193
+
*
194
+
* @return void
195
+
*/
196
+
protected function render_video_background() {
197
+
$settings = $this->get_settings_for_display();
198
+
199
+
if ( 'video' !== $settings['background_background'] ) {
200
+
return;
201
+
}
202
+
203
+
if ( ! $settings['background_video_link'] ) {
204
+
return;
205
+
}
206
+
207
+
$video_properties = Embed::get_video_properties( $settings['background_video_link'] );
208
+
209
+
$this->add_render_attribute(
210
+
'background-video-container',
211
+
[
212
+
'class' => 'elementor-background-video-container',
213
+
'aria-hidden' => 'true',
214
+
]
215
+
);
216
+
217
+
if ( ! $settings['background_play_on_mobile'] ) {
218
+
$this->add_render_attribute( 'background-video-container', 'class', 'elementor-hidden-mobile' );
219
+
}
220
+
221
+
?><div <?php $this->print_render_attribute_string( 'background-video-container' ); ?>>
222
+
<?php if ( $video_properties ) : ?>
223
+
<div class="elementor-background-video-embed"></div>
224
+
<?php
225
+
else :
226
+
$video_tag_attributes = 'autoplay muted playsinline';
227
+
228
+
if ( 'yes' !== $settings['background_play_once'] ) {
229
+
$video_tag_attributes .= ' loop';
230
+
}
231
+
?>
232
+
<video class="elementor-background-video-hosted" <?php echo esc_attr( $video_tag_attributes ); ?>></video>
233
+
<?php endif; ?>
234
+
</div><?php
235
+
}
236
+
237
+
/**
238
+
* Render the Container's shape divider.
239
+
* TODO: Copied from `section.php`.
240
+
*
241
+
* Used to generate the shape dividers HTML.
242
+
*
243
+
* @param string $side - Shape divider side, used to set the shape key.
244
+
*
245
+
* @return void
246
+
*/
247
+
protected function render_shape_divider( $side ) {
248
+
$settings = $this->get_active_settings();
249
+
$base_setting_key = "shape_divider_$side";
250
+
$negative = ! empty( $settings[ $base_setting_key . '_negative' ] );
251
+
$shape_path = Shapes::get_shape_path( $settings[ $base_setting_key ], $negative );
252
+
253
+
if ( ! is_file( $shape_path ) || ! is_readable( $shape_path ) ) {
254
+
return;
255
+
}
256
+
?>
257
+
<div class="elementor-shape elementor-shape-<?php echo esc_attr( $side ); ?>" aria-hidden="true" data-negative="<?php
258
+
Utils::print_unescaped_internal_string( $negative ? 'true' : 'false' );
259
+
?>">
260
+
<?php
261
+
// PHPCS - The file content is being read from a strict file path structure.
262
+
echo Utils::file_get_contents( $shape_path ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
263
+
?>
264
+
</div>
265
+
<?php
266
+
}
267
+
268
+
/**
269
+
* Print safe HTML tag for the element based on the element settings.
270
+
*
271
+
* @return void
272
+
*/
273
+
protected function print_html_tag() {
274
+
$html_tag = $this->get_settings( 'html_tag' );
275
+
276
+
if ( empty( $html_tag ) ) {
277
+
$html_tag = 'div';
278
+
}
279
+
280
+
Utils::print_validated_html_tag( $html_tag );
281
+
}
282
+
283
+
/**
284
+
* Before rendering the container content. (Print the opening tag, etc.)
285
+
*
286
+
* @return void
287
+
*/
288
+
public function before_render() {
289
+
$settings = $this->get_settings_for_display();
290
+
$link = $settings['link'];
291
+
292
+
if ( ! empty( $link['url'] ) ) {
293
+
$this->add_link_attributes( '_wrapper', $link );
294
+
}
295
+
296
+
?><<?php $this->print_html_tag(); ?> <?php $this->print_render_attribute_string( '_wrapper' ); ?>>
297
+
<?php
298
+
if ( $this->is_boxed_container( $settings ) ) { ?>
299
+
<div class="e-con-inner">
300
+
<?php }
301
+
302
+
$this->render_video_background();
303
+
304
+
if ( ! empty( $settings['shape_divider_top'] ) ) {
305
+
$this->render_shape_divider( 'top' );
306
+
}
307
+
308
+
if ( ! empty( $settings['shape_divider_bottom'] ) ) {
309
+
$this->render_shape_divider( 'bottom' );
310
+
}
311
+
}
312
+
313
+
/**
314
+
* After rendering the Container content. (Print the closing tag, etc.)
315
+
*
316
+
* @return void
317
+
*/
318
+
public function after_render() {
319
+
$settings = $this->get_settings_for_display();
320
+
if ( $this->is_boxed_container( $settings ) ) { ?>
321
+
</div>
322
+
<?php } ?>
323
+
</<?php $this->print_html_tag(); ?>>
324
+
<?php
325
+
}
326
+
327
+
protected function is_boxed_container( array $settings ) {
328
+
return ! empty( $settings['content_width'] ) && 'boxed' === $settings['content_width'];
329
+
}
330
+
331
+
/**
332
+
* Override the default child type to allow widgets & containers as children.
333
+
*
334
+
* @param array $element_data
335
+
*
336
+
* @return \Elementor\Element_Base|\Elementor\Widget_Base|null
337
+
*/
338
+
protected function _get_default_child_type( array $element_data ) {
339
+
$el_types = array_keys( Plugin::$instance->elements_manager->get_element_types() );
340
+
341
+
if ( in_array( $element_data['elType'], $el_types, true ) ) {
342
+
return Plugin::$instance->elements_manager->get_element_types( $element_data['elType'] );
343
+
}
344
+
345
+
if ( ! isset( $element_data['widgetType'] ) ) {
346
+
return null;
347
+
}
348
+
349
+
return Plugin::$instance->widgets_manager->get_widget_types( $element_data['widgetType'] );
350
+
}
351
+
352
+
/**
353
+
* Register the Container's layout controls.
354
+
*
355
+
* @return void
356
+
*/
357
+
protected function register_container_layout_controls() {
358
+
$this->start_controls_section(
359
+
'section_layout_container',
360
+
[
361
+
'label' => esc_html__( 'Container', 'elementor' ),
362
+
'tab' => Controls_Manager::TAB_LAYOUT,
363
+
]
364
+
);
365
+
366
+
$active_breakpoints = Plugin::$instance->breakpoints->get_active_breakpoints();
367
+
368
+
if ( array_key_exists( Breakpoints_Manager::BREAKPOINT_KEY_MOBILE_EXTRA, $active_breakpoints ) ) {
369
+
$min_affected_device = Breakpoints_Manager::BREAKPOINT_KEY_MOBILE_EXTRA;
370
+
} else {
371
+
$min_affected_device = Breakpoints_Manager::BREAKPOINT_KEY_TABLET;
372
+
}
373
+
374
+
$this->add_control(
375
+
'container_type',
376
+
[
377
+
'label' => esc_html__( 'Container Layout', 'elementor' ),
378
+
'type' => Controls_Manager::SELECT,
379
+
'default' => 'flex',
380
+
'prefix_class' => 'e-',
381
+
'options' => [
382
+
'flex' => esc_html__( 'Flexbox', 'elementor' ),
383
+
'grid' => esc_html__( 'Grid', 'elementor' ),
384
+
],
385
+
'selectors' => [
386
+
'{{WRAPPER}}' => '--display: {{VALUE}}',
387
+
],
388
+
'separator' => 'after',
389
+
'editor_available' => true,
390
+
]
391
+
);
392
+
393
+
$this->add_control(
394
+
'content_width',
395
+
[
396
+
'label' => esc_html__( 'Content Width', 'elementor' ),
397
+
'type' => Controls_Manager::SELECT,
398
+
'default' => 'boxed',
399
+
'options' => [
400
+
'boxed' => esc_html__( 'Boxed', 'elementor' ),
401
+
'full' => esc_html__( 'Full Width', 'elementor' ),
402
+
],
403
+
'render_type' => 'template',
404
+
'prefix_class' => 'e-con-',
405
+
'editor_available' => true,
406
+
]
407
+
);
408
+
409
+
$width_control_settings = [
410
+
'label' => esc_html__( 'Width', 'elementor' ),
411
+
'type' => Controls_Manager::SLIDER,
412
+
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
413
+
'range' => [
414
+
'px' => [
415
+
'min' => 500,
416
+
'max' => 1600,
417
+
],
418
+
],
419
+
'default' => [
420
+
'unit' => '%',
421
+
],
422
+
'min_affected_device' => [
423
+
Breakpoints_Manager::BREAKPOINT_KEY_DESKTOP => $min_affected_device,
424
+
Breakpoints_Manager::BREAKPOINT_KEY_LAPTOP => $min_affected_device,
425
+
Breakpoints_Manager::BREAKPOINT_KEY_TABLET_EXTRA => $min_affected_device,
426
+
Breakpoints_Manager::BREAKPOINT_KEY_TABLET => $min_affected_device,
427
+
Breakpoints_Manager::BREAKPOINT_KEY_MOBILE_EXTRA => $min_affected_device,
428
+
],
429
+
];
430
+
431
+
$this->add_responsive_control(
432
+
'width',
433
+
array_merge( $width_control_settings, [
434
+
'selectors' => [
435
+
'{{WRAPPER}}' => '--width: {{SIZE}}{{UNIT}};',
436
+
],
437
+
'condition' => [
438
+
'content_width' => 'full',
439
+
],
440
+
'device_args' => [
441
+
Breakpoints_Manager::BREAKPOINT_KEY_DESKTOP => [
442
+
'placeholder' => [
443
+
'size' => 100,
444
+
'unit' => '%',
445
+
],
446
+
],
447
+
Breakpoints_Manager::BREAKPOINT_KEY_MOBILE => [
448
+
// The mobile width is not inherited from the higher breakpoint width controls.
449
+
'placeholder' => [
450
+
'size' => 100,
451
+
'unit' => '%',
452
+
],
453
+
],
454
+
],
455
+
] )
456
+
);
457
+
458
+
$this->add_responsive_control(
459
+
'boxed_width',
460
+
array_merge( $width_control_settings, [
461
+
'selectors' => [
462
+
'{{WRAPPER}}' => '--content-width: {{SIZE}}{{UNIT}};',
463
+
],
464
+
'condition' => [
465
+
'content_width' => 'boxed',
466
+
],
467
+
'default' => [
468
+
'unit' => 'px',
469
+
],
470
+
'device_args' => [
471
+
Breakpoints_Manager::BREAKPOINT_KEY_DESKTOP => [
472
+
// Use the default width from the kit as a placeholder.
473
+
'placeholder' => $this->active_kit->get_settings_for_display( 'container_width' ),
474
+
],
475
+
Breakpoints_Manager::BREAKPOINT_KEY_MOBILE => [
476
+
// The mobile width is not inherited from the higher breakpoint width controls.
477
+
'placeholder' => [
478
+
'size' => 100,
479
+
'unit' => '%',
480
+
],
481
+
],
482
+
],
483
+
] )
484
+
);
485
+
486
+
$this->add_responsive_control(
487
+
'min_height',
488
+
[
489
+
'label' => esc_html__( 'Min Height', 'elementor' ),
490
+
'type' => Controls_Manager::SLIDER,
491
+
'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ],
492
+
'range' => [
493
+
'px' => [
494
+
'max' => 1440,
495
+
],
496
+
],
497
+
'description' => sprintf(
498
+
/* translators: %s: 100vh. */
499
+
esc_html__( 'To achieve full height Container use %s.', 'elementor' ),
500
+
'100vh'
501
+
),
502
+
'selectors' => [
503
+
'{{WRAPPER}}' => '--min-height: {{SIZE}}{{UNIT}};',
504
+
],
505
+
]
506
+
);
507
+
508
+
$this->add_group_control(
509
+
Group_Control_Flex_Container::get_type(),
510
+
[
511
+
'name' => 'flex',
512
+
'selector' => '{{WRAPPER}}',
513
+
'fields_options' => [
514
+
'gap' => [
515
+
'label' => esc_html__( 'Gaps', 'elementor' ),
516
+
'device_args' => [
517
+
Breakpoints_Manager::BREAKPOINT_KEY_DESKTOP => [
518
+
// Use the default gap from the kit as a placeholder.
519
+
'placeholder' => $this->active_kit->get_settings_for_display( 'space_between_widgets' ),
520
+
],
521
+
],
522
+
],
523
+
],
524
+
'condition' => [
525
+
'container_type' => [ 'flex' ],
526
+
],
527
+
]
528
+
);
529
+
530
+
$this->add_group_control(
531
+
Group_Control_Grid_Container::get_type(),
532
+
[
533
+
'name' => 'grid',
534
+
'selector' => '{{WRAPPER}}',
535
+
'condition' => [
536
+
'container_type' => [ 'grid' ],
537
+
],
538
+
]
539
+
);
540
+
541
+
$this->end_controls_section();
542
+
}
543
+
544
+
/**
545
+
* Register the Container's items layout controls.
546
+
*
547
+
* @return void
548
+
*/
549
+
protected function register_items_layout_controls() {
550
+
$this->start_controls_section(
551
+
'section_layout_additional_options',
552
+
[
553
+
'label' => esc_html__( 'Additional Options', 'elementor' ),
554
+
'tab' => Controls_Manager::TAB_LAYOUT,
555
+
]
556
+
);
557
+
558
+
$this->add_control(
559
+
'overflow',
560
+
[
561
+
'label' => esc_html__( 'Overflow', 'elementor' ),
562
+
'type' => Controls_Manager::SELECT,
563
+
'default' => '',
564
+
'options' => [
565
+
'' => esc_html__( 'Default', 'elementor' ),
566
+
'hidden' => esc_html__( 'Hidden', 'elementor' ),
567
+
'auto' => esc_html__( 'Auto', 'elementor' ),
568
+
],
569
+
'selectors' => [
570
+
'{{WRAPPER}}' => '--overflow: {{VALUE}}',
571
+
],
572
+
]
573
+
);
574
+
575
+
$possible_tags = [
576
+
'div' => 'div',
577
+
'header' => 'header',
578
+
'footer' => 'footer',
579
+
'main' => 'main',
580
+
'article' => 'article',
581
+
'section' => 'section',
582
+
'aside' => 'aside',
583
+
'nav' => 'nav',
584
+
'a' => 'a ' . esc_html__( '(link)', 'elementor' ),
585
+
];
586
+
587
+
$options = [
588
+
'' => esc_html__( 'Default', 'elementor' ),
589
+
] + $possible_tags;
590
+
591
+
$this->add_control(
592
+
'html_tag',
593
+
[
594
+
'label' => esc_html__( 'HTML Tag', 'elementor' ),
595
+
'type' => Controls_Manager::SELECT,
596
+
'options' => $options,
597
+
]
598
+
);
599
+
600
+
$this->add_control(
601
+
'link_note',
602
+
[
603
+
'type' => Controls_Manager::ALERT,
604
+
'alert_type' => 'warning',
605
+
'content' => esc_html__( 'Don’t add links to elements nested in this container - it will break the layout.', 'elementor' ),
606
+
'condition' => [
607
+
'html_tag' => 'a',
608
+
],
609
+
]
610
+
);
611
+
612
+
$this->add_control(
613
+
'link',
614
+
[
615
+
'label' => esc_html__( 'Link', 'elementor' ),
616
+
'type' => Controls_Manager::URL,
617
+
'dynamic' => [
618
+
'active' => true,
619
+
],
620
+
'condition' => [
621
+
'html_tag' => 'a',
622
+
],
623
+
]
624
+
);
625
+
626
+
$this->end_controls_section();
627
+
}
628
+
629
+
/**
630
+
* Register the Container's layout tab.
631
+
*
632
+
* @return void
633
+
*/
634
+
protected function register_layout_tab() {
635
+
$this->register_container_layout_controls();
636
+
637
+
$this->register_items_layout_controls();
638
+
}
639
+
640
+
/**
641
+
* Register the Container's background controls.
642
+
*
643
+
* @return void
644
+
*/
645
+
protected function register_background_controls() {
646
+
$this->start_controls_section(
647
+
'section_background',
648
+
[
649
+
'label' => esc_html__( 'Background', 'elementor' ),
650
+
'tab' => Controls_Manager::TAB_STYLE,
651
+
]
652
+
);
653
+
654
+
$this->start_controls_tabs( 'tabs_background' );
655
+
656
+
/**
657
+
* Normal.
658
+
*/
659
+
$this->start_controls_tab(
660
+
'tab_background_normal',
661
+
[
662
+
'label' => esc_html__( 'Normal', 'elementor' ),
663
+
]
664
+
);
665
+
666
+
$this->add_group_control(
667
+
Group_Control_Background::get_type(),
668
+
[
669
+
'name' => 'background',
670
+
'types' => [ 'classic', 'gradient', 'video', 'slideshow' ],
671
+
'fields_options' => [
672
+
'background' => [
673
+
'frontend_available' => true,
674
+
],
675
+
],
676
+
]
677
+
);
678
+
679
+
$this->add_control(
680
+
'handle_slideshow_asset_loading',
681
+
[
682
+
'type' => Controls_Manager::HIDDEN,
683
+
'assets' => [
684
+
'styles' => [
685
+
[
686
+
'name' => 'e-swiper',
687
+
'conditions' => [
688
+
'terms' => [
689
+
[
690
+
'name' => 'background_background',
691
+
'operator' => '===',
692
+
'value' => 'slideshow',
693
+
],
694
+
],
695
+
],
696
+
],
697
+
],
698
+
'scripts' => [
699
+
[
700
+
'name' => 'swiper',
701
+
'conditions' => [
702
+
'terms' => [
703
+
[
704
+
'name' => 'background_background',
705
+
'operator' => '===',
706
+
'value' => 'slideshow',
707
+
],
708
+
],
709
+
],
710
+
],
711
+
],
712
+
],
713
+
]
714
+
);
715
+
716
+
$this->end_controls_tab();
717
+
718
+
/**
719
+
* Hover.
720
+
*/
721
+
$this->start_controls_tab(
722
+
'tab_background_hover',
723
+
[
724
+
'label' => esc_html__( 'Hover', 'elementor' ),
725
+
]
726
+
);
727
+
728
+
$this->add_group_control(
729
+
Group_Control_Background::get_type(),
730
+
[
731
+
'name' => 'background_hover',
732
+
'selector' => '{{WRAPPER}}:hover',
733
+
]
734
+
);
735
+
736
+
$this->add_control(
737
+
'background_hover_transition',
738
+
[
739
+
'label' => esc_html__( 'Transition Duration', 'elementor' ) . ' (s)',
740
+
'type' => Controls_Manager::SLIDER,
741
+
'default' => [
742
+
'size' => 0.3,
743
+
],
744
+
'range' => [
745
+
'px' => [
746
+
'min' => 0,
747
+
'max' => 3,
748
+
'step' => 0.1,
749
+
],
750
+
],
751
+
'render_type' => 'ui',
752
+
'separator' => 'before',
753
+
'condition' => [
754
+
'background_hover_background' => [ 'classic', 'gradient' ],
755
+
],
756
+
'selectors' => [
757
+
'{{WRAPPER}}' => '--background-transition: {{SIZE}}s;',
758
+
],
759
+
]
760
+
);
761
+
762
+
$this->end_controls_tab();
763
+
764
+
$this->end_controls_tabs();
765
+
766
+
$this->end_controls_section();
767
+
}
768
+
769
+
/**
770
+
* Register the Container's background overlay controls.
771
+
*
772
+
* @return void
773
+
*/
774
+
protected function register_background_overlay_controls() {
775
+
$this->start_controls_section(
776
+
'section_background_overlay',
777
+
[
778
+
'label' => esc_html__( 'Background Overlay', 'elementor' ),
779
+
'tab' => Controls_Manager::TAB_STYLE,
780
+
]
781
+
);
782
+
783
+
$this->start_controls_tabs( 'tabs_background_overlay' );
784
+
785
+
/**
786
+
* Normal.
787
+
*/
788
+
$this->start_controls_tab(
789
+
'tab_background_overlay',
790
+
[
791
+
'label' => esc_html__( 'Normal', 'elementor' ),
792
+
]
793
+
);
794
+
795
+
$background_overlay_selector = '{{WRAPPER}}::before, {{WRAPPER}} > .elementor-background-video-container::before, {{WRAPPER}} > .e-con-inner > .elementor-background-video-container::before, {{WRAPPER}} > .elementor-background-slideshow::before, {{WRAPPER}} > .e-con-inner > .elementor-background-slideshow::before, {{WRAPPER}} > .elementor-motion-effects-container > .elementor-motion-effects-layer::before';
796
+
797
+
$this->add_group_control(
798
+
Group_Control_Background::get_type(),
799
+
[
800
+
'name' => 'background_overlay',
801
+
'selector' => $background_overlay_selector,
802
+
'fields_options' => [
803
+
'background' => [
804
+
'selectors' => [
805
+
// Hack to set the `::before` content in order to render it only when there is a background overlay.
806
+
$background_overlay_selector => '--background-overlay: \'\';',
807
+
],
808
+
],
809
+
],
810
+
]
811
+
);
812
+
813
+
$this->add_responsive_control(
814
+
'background_overlay_opacity',
815
+
[
816
+
'label' => esc_html__( 'Opacity', 'elementor' ),
817
+
'type' => Controls_Manager::SLIDER,
818
+
'default' => [
819
+
'size' => .5,
820
+
],
821
+
'range' => [
822
+
'px' => [
823
+
'max' => 1,
824
+
'step' => 0.01,
825
+
],
826
+
],
827
+
'selectors' => [
828
+
'{{WRAPPER}}' => '--overlay-opacity: {{SIZE}};',
829
+
],
830
+
'condition' => [
831
+
'background_overlay_background' => [ 'classic', 'gradient' ],
832
+
],
833
+
]
834
+
);
835
+
836
+
$this->add_group_control(
837
+
Group_Control_Css_Filter::get_type(),
838
+
[
839
+
'name' => 'css_filters',
840
+
'selector' => '{{WRAPPER}}::before',
841
+
'conditions' => [
842
+
'relation' => 'or',
843
+
'terms' => [
844
+
[
845
+
'name' => 'background_overlay_image[url]',
846
+
'operator' => '!==',
847
+
'value' => '',
848
+
],
849
+
[
850
+
'name' => 'background_overlay_color',
851
+
'operator' => '!==',
852
+
'value' => '',
853
+
],
854
+
],
855
+
],
856
+
]
857
+
);
858
+
859
+
$this->add_control(
860
+
'overlay_blend_mode',
861
+
[
862
+
'label' => esc_html__( 'Blend Mode', 'elementor' ),
863
+
'type' => Controls_Manager::SELECT,
864
+
'options' => [
865
+
'' => esc_html__( 'Normal', 'elementor' ),
866
+
'multiply' => esc_html__( 'Multiply', 'elementor' ),
867
+
'screen' => esc_html__( 'Screen', 'elementor' ),
868
+
'overlay' => esc_html__( 'Overlay', 'elementor' ),
869
+
'darken' => esc_html__( 'Darken', 'elementor' ),
870
+
'lighten' => esc_html__( 'Lighten', 'elementor' ),
871
+
'color-dodge' => esc_html__( 'Color Dodge', 'elementor' ),
872
+
'saturation' => esc_html__( 'Saturation', 'elementor' ),
873
+
'color' => esc_html__( 'Color', 'elementor' ),
874
+
'luminosity' => esc_html__( 'Luminosity', 'elementor' ),
875
+
],
876
+
'selectors' => [
877
+
'{{WRAPPER}}' => '--overlay-mix-blend-mode: {{VALUE}}',
878
+
],
879
+
'conditions' => [
880
+
'relation' => 'or',
881
+
'terms' => [
882
+
[
883
+
'name' => 'background_overlay_image[url]',
884
+
'operator' => '!==',
885
+
'value' => '',
886
+
],
887
+
[
888
+
'name' => 'background_overlay_color',
889
+
'operator' => '!==',
890
+
'value' => '',
891
+
],
892
+
],
893
+
],
894
+
]
895
+
);
896
+
897
+
$this->end_controls_tab();
898
+
899
+
/**
900
+
* Hover.
901
+
*/
902
+
$this->start_controls_tab(
903
+
'tab_background_overlay_hover',
904
+
[
905
+
'label' => esc_html__( 'Hover', 'elementor' ),
906
+
]
907
+
);
908
+
909
+
$background_overlay_hover_selector = '{{WRAPPER}}:hover::before, {{WRAPPER}}:hover > .elementor-background-video-container::before, {{WRAPPER}}:hover > .e-con-inner > .elementor-background-video-container::before, {{WRAPPER}} > .elementor-background-slideshow:hover::before, {{WRAPPER}} > .e-con-inner > .elementor-background-slideshow:hover::before';
910
+
911
+
$this->add_group_control(
912
+
Group_Control_Background::get_type(),
913
+
[
914
+
'name' => 'background_overlay_hover',
915
+
'selector' => $background_overlay_hover_selector,
916
+
'fields_options' => [
917
+
'background' => [
918
+
'selectors' => [
919
+
// Hack to set the `::before` content in order to render it only when there is a background overlay.
920
+
$background_overlay_hover_selector => '--background-overlay: \'\';',
921
+
],
922
+
],
923
+
],
924
+
]
925
+
);
926
+
927
+
$this->add_responsive_control(
928
+
'background_overlay_hover_opacity',
929
+
[
930
+
'label' => esc_html__( 'Opacity', 'elementor' ),
931
+
'type' => Controls_Manager::SLIDER,
932
+
'default' => [
933
+
'size' => .5,
934
+
],
935
+
'range' => [
936
+
'px' => [
937
+
'max' => 1,
938
+
'step' => 0.01,
939
+
],
940
+
],
941
+
'selectors' => [
942
+
'{{WRAPPER}}:hover' => '--overlay-opacity: {{SIZE}};',
943
+
],
944
+
'condition' => [
945
+
'background_overlay_hover_background' => [ 'classic', 'gradient' ],
946
+
],
947
+
]
948
+
);
949
+
950
+
$this->add_control(
951
+
'background_overlay_hover_transition',
952
+
[
953
+
'label' => esc_html__( 'Transition Duration', 'elementor' ) . ' (s)',
954
+
'type' => Controls_Manager::SLIDER,
955
+
'range' => [
956
+
'px' => [
957
+
'min' => 0,
958
+
'max' => 3,
959
+
'step' => 0.1,
960
+
],
961
+
],
962
+
'render_type' => 'ui',
963
+
'separator' => 'before',
964
+
'condition' => [
965
+
'background_overlay_hover_background' => [ 'classic', 'gradient' ],
966
+
],
967
+
'selectors' => [
968
+
'{{WRAPPER}}, {{WRAPPER}}::before' => '--overlay-transition: {{SIZE}}s;',
969
+
],
970
+
]
971
+
);
972
+
973
+
$this->add_group_control(
974
+
Group_Control_Css_Filter::get_type(),
975
+
[
976
+
'name' => 'css_filters_hover',
977
+
'selector' => '{{WRAPPER}}:hover::before',
978
+
]
979
+
);
980
+
981
+
$this->end_controls_tab();
982
+
983
+
$this->end_controls_tabs();
984
+
985
+
$this->end_controls_section();
986
+
}
987
+
988
+
/**
989
+
* Register the Container's border controls.
990
+
*
991
+
* @return void
992
+
*/
993
+
protected function register_border_controls() {
994
+
$this->start_controls_section(
995
+
'section_border',
996
+
[
997
+
'label' => esc_html__( 'Border', 'elementor' ),
998
+
'tab' => Controls_Manager::TAB_STYLE,
999
+
]
1000
+
);
1001
+
1002
+
$this->start_controls_tabs( 'tabs_border' );
1003
+
1004
+
/**
1005
+
* Normal.
1006
+
*/
1007
+
$this->start_controls_tab(
1008
+
'tab_border',
1009
+
[
1010
+
'label' => esc_html__( 'Normal', 'elementor' ),
1011
+
]
1012
+
);
1013
+
1014
+
$this->add_group_control(
1015
+
Group_Control_Border::get_type(),
1016
+
[
1017
+
'name' => 'border',
1018
+
'selector' => '{{WRAPPER}}',
1019
+
'fields_options' => [
1020
+
'width' => [
1021
+
'selectors' => [
1022
+
'{{SELECTOR}}' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}; --border-top-width: {{TOP}}{{UNIT}}; --border-right-width: {{RIGHT}}{{UNIT}}; --border-bottom-width: {{BOTTOM}}{{UNIT}}; --border-left-width: {{LEFT}}{{UNIT}};',
1023
+
],
1024
+
],
1025
+
'color' => [
1026
+
'selectors' => [
1027
+
'{{SELECTOR}}' => 'border-color: {{VALUE}}; --border-color: {{VALUE}};',
1028
+
],
1029
+
],
1030
+
'border' => [
1031
+
'selectors' => [
1032
+
'{{SELECTOR}}' => 'border-style: {{VALUE}}; --border-style: {{VALUE}};',
1033
+
],
1034
+
],
1035
+
],
1036
+
]
1037
+
);
1038
+
1039
+
$this->add_responsive_control(
1040
+
'border_radius',
1041
+
[
1042
+
'label' => esc_html__( 'Border Radius', 'elementor' ),
1043
+
'type' => Controls_Manager::DIMENSIONS,
1044
+
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
1045
+
'selectors' => [
1046
+
'{{WRAPPER}}' => '--border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1047
+
],
1048
+
]
1049
+
);
1050
+
1051
+
$this->add_group_control(
1052
+
Group_Control_Box_Shadow::get_type(),
1053
+
[
1054
+
'name' => 'box_shadow',
1055
+
]
1056
+
);
1057
+
1058
+
$this->end_controls_tab();
1059
+
1060
+
/**
1061
+
* Hover.
1062
+
*/
1063
+
$this->start_controls_tab(
1064
+
'tab_border_hover',
1065
+
[
1066
+
'label' => esc_html__( 'Hover', 'elementor' ),
1067
+
]
1068
+
);
1069
+
1070
+
$this->add_group_control(
1071
+
Group_Control_Border::get_type(),
1072
+
[
1073
+
'name' => 'border_hover',
1074
+
'selector' => '{{WRAPPER}}:hover',
1075
+
'fields_options' => [
1076
+
'width' => [
1077
+
'selectors' => [
1078
+
'{{SELECTOR}}' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}; --border-top-width: {{TOP}}{{UNIT}}; --border-right-width: {{RIGHT}}{{UNIT}}; --border-bottom-width: {{BOTTOM}}{{UNIT}}; --border-left-width: {{LEFT}}{{UNIT}};',
1079
+
],
1080
+
],
1081
+
'color' => [
1082
+
'selectors' => [
1083
+
'{{SELECTOR}}' => 'border-color: {{VALUE}}; --border-color: {{VALUE}};',
1084
+
],
1085
+
],
1086
+
],
1087
+
]
1088
+
);
1089
+
1090
+
$this->add_responsive_control(
1091
+
'border_radius_hover',
1092
+
[
1093
+
'label' => esc_html__( 'Border Radius', 'elementor' ),
1094
+
'type' => Controls_Manager::DIMENSIONS,
1095
+
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
1096
+
'selectors' => [
1097
+
'{{WRAPPER}}:hover' => '--border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}; --border-top-left-radius: {{TOP}}{{UNIT}}; --border-top-right-radius: {{RIGHT}}{{UNIT}}; --border-bottom-right-radius: {{BOTTOM}}{{UNIT}}; --border-bottom-left-radius: {{LEFT}}{{UNIT}};',
1098
+
],
1099
+
]
1100
+
);
1101
+
1102
+
$this->add_group_control(
1103
+
Group_Control_Box_Shadow::get_type(),
1104
+
[
1105
+
'name' => 'box_shadow_hover',
1106
+
'selector' => '{{WRAPPER}}:hover',
1107
+
]
1108
+
);
1109
+
1110
+
$this->add_control(
1111
+
'border_hover_transition',
1112
+
[
1113
+
'label' => esc_html__( 'Transition Duration', 'elementor' ) . ' (s)',
1114
+
'type' => Controls_Manager::SLIDER,
1115
+
'separator' => 'before',
1116
+
'default' => [
1117
+
'size' => 0.3,
1118
+
],
1119
+
'range' => [
1120
+
'px' => [
1121
+
'min' => 0,
1122
+
'max' => 3,
1123
+
'step' => 0.1,
1124
+
],
1125
+
],
1126
+
'conditions' => [
1127
+
'relation' => 'or',
1128
+
'terms' => [
1129
+
[
1130
+
'name' => 'border_hover_border',
1131
+
'operator' => '!==',
1132
+
'value' => '',
1133
+
],
1134
+
[
1135
+
'name' => 'border_radius_hover[top]',
1136
+
'operator' => '!==',
1137
+
'value' => '',
1138
+
],
1139
+
[
1140
+
'name' => 'border_radius_hover[right]',
1141
+
'operator' => '!==',
1142
+
'value' => '',
1143
+
],
1144
+
[
1145
+
'name' => 'border_radius_hover[bottom]',
1146
+
'operator' => '!==',
1147
+
'value' => '',
1148
+
],
1149
+
[
1150
+
'name' => 'border_radius_hover[left]',
1151
+
'operator' => '!==',
1152
+
'value' => '',
1153
+
],
1154
+
],
1155
+
],
1156
+
'selectors' => [
1157
+
'{{WRAPPER}}, {{WRAPPER}}::before' => '--border-transition: {{SIZE}}s;',
1158
+
],
1159
+
]
1160
+
);
1161
+
1162
+
$this->end_controls_tab();
1163
+
1164
+
$this->end_controls_tabs();
1165
+
1166
+
$this->end_controls_section();
1167
+
}
1168
+
1169
+
/**
1170
+
* Register the Container's shape dividers controls.
1171
+
* TODO: Copied from `section.php`.
1172
+
*
1173
+
* @return void
1174
+
*/
1175
+
protected function register_shape_dividers_controls() {
1176
+
$this->start_controls_section(
1177
+
'section_shape_divider',
1178
+
[
1179
+
'label' => esc_html__( 'Shape Divider', 'elementor' ),
1180
+
'tab' => Controls_Manager::TAB_STYLE,
1181
+
]
1182
+
);
1183
+
1184
+
$this->start_controls_tabs( 'tabs_shape_dividers' );
1185
+
1186
+
foreach ( [
1187
+
'top' => esc_html__( 'Top', 'elementor' ),
1188
+
'bottom' => esc_html__( 'Bottom', 'elementor' ),
1189
+
] as $side => $side_label ) {
1190
+
$base_control_key = "shape_divider_$side";
1191
+
1192
+
$this->start_controls_tab(
1193
+
"tab_$base_control_key",
1194
+
[
1195
+
'label' => $side_label,
1196
+
]
1197
+
);
1198
+
1199
+
$this->add_control(
1200
+
$base_control_key,
1201
+
[
1202
+
'label' => esc_html__( 'Type', 'elementor' ),
1203
+
'type' => Controls_Manager::VISUAL_CHOICE,
1204
+
'label_block' => true,
1205
+
'columns' => 2,
1206
+
'options' => Shapes::get_shapes(),
1207
+
'render_type' => 'none',
1208
+
'frontend_available' => true,
1209
+
'assets' => [
1210
+
'styles' => [
1211
+
[
1212
+
'name' => 'e-shapes',
1213
+
'conditions' => [
1214
+
'terms' => [
1215
+
[
1216
+
'name' => $base_control_key,
1217
+
'operator' => '!==',
1218
+
'value' => '',
1219
+
],
1220
+
],
1221
+
],
1222
+
],
1223
+
],
1224
+
],
1225
+
]
1226
+
);
1227
+
1228
+
$this->add_control(
1229
+
$base_control_key . '_color',
1230
+
[
1231
+
'label' => esc_html__( 'Color', 'elementor' ),
1232
+
'type' => Controls_Manager::COLOR,
1233
+
'condition' => [
1234
+
"shape_divider_$side!" => '',
1235
+
],
1236
+
'selectors' => [
1237
+
"{{WRAPPER}} > .elementor-shape-$side .elementor-shape-fill, {{WRAPPER}} > .e-con-inner > .elementor-shape-$side .elementor-shape-fill" => 'fill: {{UNIT}};',
1238
+
],
1239
+
]
1240
+
);
1241
+
1242
+
$this->add_responsive_control(
1243
+
$base_control_key . '_width',
1244
+
[
1245
+
'label' => esc_html__( 'Width', 'elementor' ),
1246
+
'type' => Controls_Manager::SLIDER,
1247
+
'size_units' => [ '%', 'vw', 'custom' ],
1248
+
'default' => [
1249
+
'unit' => '%',
1250
+
],
1251
+
'tablet_default' => [
1252
+
'unit' => '%',
1253
+
],
1254
+
'mobile_default' => [
1255
+
'unit' => '%',
1256
+
],
1257
+
'range' => [
1258
+
'%' => [
1259
+
'min' => 100,
1260
+
'max' => 300,
1261
+
],
1262
+
'vw' => [
1263
+
'min' => 100,
1264
+
'max' => 300,
1265
+
],
1266
+
],
1267
+
'condition' => [
1268
+
"shape_divider_$side" => array_keys( Shapes::filter_shapes( 'height_only', Shapes::FILTER_EXCLUDE ) ),
1269
+
],
1270
+
'selectors' => [
1271
+
"{{WRAPPER}} > .elementor-shape-$side svg, {{WRAPPER}} > .e-con-inner > .elementor-shape-$side svg" => 'width: calc({{SIZE}}{{UNIT}} + 1.3px)',
1272
+
],
1273
+
]
1274
+
);
1275
+
1276
+
$this->add_responsive_control(
1277
+
$base_control_key . '_height',
1278
+
[
1279
+
'label' => esc_html__( 'Height', 'elementor' ),
1280
+
'type' => Controls_Manager::SLIDER,
1281
+
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
1282
+
'range' => [
1283
+
'px' => [
1284
+
'max' => 500,
1285
+
],
1286
+
'em' => [
1287
+
'max' => 50,
1288
+
],
1289
+
'rem' => [
1290
+
'max' => 50,
1291
+
],
1292
+
],
1293
+
'condition' => [
1294
+
"shape_divider_$side!" => '',
1295
+
],
1296
+
'selectors' => [
1297
+
"{{WRAPPER}} > .elementor-shape-$side svg, {{WRAPPER}} > .e-con-inner > .elementor-shape-$side svg" => 'height: {{SIZE}}{{UNIT}};',
1298
+
],
1299
+
]
1300
+
);
1301
+
1302
+
$this->add_control(
1303
+
$base_control_key . '_flip',
1304
+
[
1305
+
'label' => esc_html__( 'Flip', 'elementor' ),
1306
+
'type' => Controls_Manager::SWITCHER,
1307
+
'condition' => [
1308
+
"shape_divider_$side" => array_keys( Shapes::filter_shapes( 'has_flip' ) ),
1309
+
],
1310
+
'selectors' => [
1311
+
"{{WRAPPER}} > .elementor-shape-$side svg, {{WRAPPER}} > .e-con-inner > .elementor-shape-$side svg" => 'transform: translateX(-50%) rotateY(180deg)',
1312
+
],
1313
+
]
1314
+
);
1315
+
1316
+
$this->add_control(
1317
+
$base_control_key . '_negative',
1318
+
[
1319
+
'label' => esc_html__( 'Invert', 'elementor' ),
1320
+
'type' => Controls_Manager::SWITCHER,
1321
+
'frontend_available' => true,
1322
+
'condition' => [
1323
+
"shape_divider_$side" => array_keys( Shapes::filter_shapes( 'has_negative' ) ),
1324
+
],
1325
+
'render_type' => 'none',
1326
+
]
1327
+
);
1328
+
1329
+
$this->add_control(
1330
+
$base_control_key . '_above_content',
1331
+
[
1332
+
'label' => esc_html__( 'Bring to Front', 'elementor' ),
1333
+
'type' => Controls_Manager::SWITCHER,
1334
+
'selectors' => [
1335
+
"{{WRAPPER}} > .elementor-shape-$side, {{WRAPPER}} > .e-con-inner > .elementor-shape-$side" => 'z-index: 2; pointer-events: none',
1336
+
],
1337
+
'condition' => [
1338
+
"shape_divider_$side!" => '',
1339
+
],
1340
+
]
1341
+
);
1342
+
1343
+
$this->end_controls_tab();
1344
+
}
1345
+
1346
+
$this->end_controls_tabs();
1347
+
1348
+
$this->end_controls_section();
1349
+
}
1350
+
/**
1351
+
* Register the Container's style tab.
1352
+
*
1353
+
* @return void
1354
+
*/
1355
+
protected function register_style_tab() {
1356
+
$this->register_background_controls();
1357
+
1358
+
$this->register_background_overlay_controls();
1359
+
1360
+
$this->register_border_controls();
1361
+
1362
+
$this->register_shape_dividers_controls();
1363
+
}
1364
+
1365
+
/**
1366
+
* Register the Container's advanced style controls.
1367
+
*
1368
+
* @return void
1369
+
*/
1370
+
protected function register_advanced_controls() {
1371
+
$this->start_controls_section(
1372
+
'section_layout',
1373
+
[
1374
+
'label' => esc_html__( 'Layout', 'elementor' ),
1375
+
'tab' => Controls_Manager::TAB_ADVANCED,
1376
+
]
1377
+
);
1378
+
1379
+
$this->add_responsive_control(
1380
+
'margin',
1381
+
[
1382
+
'label' => esc_html__( 'Margin', 'elementor' ),
1383
+
'type' => Controls_Manager::DIMENSIONS,
1384
+
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
1385
+
'selectors' => [
1386
+
'{{WRAPPER}}' => '--margin-top: {{TOP}}{{UNIT}}; --margin-bottom: {{BOTTOM}}{{UNIT}}; --margin-left: {{LEFT}}{{UNIT}}; --margin-right: {{RIGHT}}{{UNIT}};',
1387
+
],
1388
+
]
1389
+
);
1390
+
1391
+
$this->add_responsive_control(
1392
+
'padding',
1393
+
[
1394
+
'label' => esc_html__( 'Padding', 'elementor' ),
1395
+
'type' => Controls_Manager::DIMENSIONS,
1396
+
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
1397
+
'selectors' => [
1398
+
'{{WRAPPER}}' => '--padding-top: {{TOP}}{{UNIT}}; --padding-bottom: {{BOTTOM}}{{UNIT}}; --padding-left: {{LEFT}}{{UNIT}}; --padding-right: {{RIGHT}}{{UNIT}};',
1399
+
],
1400
+
]
1401
+
);
1402
+
1403
+
$this->add_control(
1404
+
'heading_grid_item',
1405
+
[
1406
+
'type' => Controls_Manager::HEADING,
1407
+
'label' => esc_html__( 'Grid Item', 'elementor' ),
1408
+
'separator' => 'before',
1409
+
]
1410
+
);
1411
+
1412
+
$this->add_responsive_control(
1413
+
'grid_column',
1414
+
[
1415
+
'label' => esc_html__( 'Column Span', 'elementor' ),
1416
+
'type' => Controls_Manager::SELECT,
1417
+
'options' => [
1418
+
'' => ' Default',
1419
+
'1' => '1',
1420
+
'2' => '2',
1421
+
'3' => '3',
1422
+
'4' => '4',
1423
+
'5' => '5',
1424
+
'6' => '6',
1425
+
'7' => '7',
1426
+
'8' => '8',
1427
+
'9' => '9',
1428
+
'10' => '10',
1429
+
'11' => '11',
1430
+
'12' => '12',
1431
+
'custom' => 'Custom',
1432
+
],
1433
+
'selectors' => [
1434
+
'{{WRAPPER}}' => 'grid-column: span {{VALUE}};',
1435
+
],
1436
+
]
1437
+
);
1438
+
1439
+
$this->add_responsive_control(
1440
+
'grid_column_custom',
1441
+
[
1442
+
'label' => esc_html__( 'Custom', 'elementor' ),
1443
+
'type' => Controls_Manager::TEXT,
1444
+
'ai' => [
1445
+
'active' => false,
1446
+
],
1447
+
'selectors' => [
1448
+
'{{WRAPPER}}' => 'grid-column: {{VALUE}}',
1449
+
],
1450
+
'condition' => [
1451
+
'grid_column' => 'custom',
1452
+
],
1453
+
]
1454
+
);
1455
+
1456
+
$this->add_responsive_control(
1457
+
'grid_row',
1458
+
[
1459
+
'label' => esc_html__( 'Row Span', 'elementor' ),
1460
+
'type' => Controls_Manager::SELECT,
1461
+
'options' => [
1462
+
'' => ' Default',
1463
+
'1' => '1',
1464
+
'2' => '2',
1465
+
'3' => '3',
1466
+
'4' => '4',
1467
+
'5' => '5',
1468
+
'6' => '6',
1469
+
'7' => '7',
1470
+
'8' => '8',
1471
+
'9' => '9',
1472
+
'10' => '10',
1473
+
'11' => '11',
1474
+
'12' => '12',
1475
+
'custom' => 'Custom',
1476
+
],
1477
+
'selectors' => [
1478
+
'{{WRAPPER}}' => 'grid-row: span {{VALUE}};',
1479
+
],
1480
+
]
1481
+
);
1482
+
1483
+
$this->add_responsive_control(
1484
+
'grid_row_custom',
1485
+
[
1486
+
'label' => esc_html__( 'Custom', 'elementor' ),
1487
+
'type' => Controls_Manager::TEXT,
1488
+
'separator' => 'after',
1489
+
'ai' => [
1490
+
'active' => false,
1491
+
],
1492
+
'selectors' => [
1493
+
'{{WRAPPER}}' => 'grid-row: {{VALUE}}',
1494
+
],
1495
+
'condition' => [
1496
+
'grid_row' => 'custom',
1497
+
],
1498
+
]
1499
+
);
1500
+
1501
+
$this->add_group_control(
1502
+
Group_Control_Flex_Item::get_type(),
1503
+
[
1504
+
'name' => '_flex',
1505
+
'include' => [
1506
+
'align_self',
1507
+
'order',
1508
+
'order_custom',
1509
+
'size',
1510
+
'grow',
1511
+
'shrink',
1512
+
],
1513
+
'selector' => '{{WRAPPER}}.e-con', // Hack to increase specificity.
1514
+
'separator' => 'before',
1515
+
]
1516
+
);
1517
+
1518
+
$this->add_control(
1519
+
'position_description',
1520
+
[
1521
+
'type' => Controls_Manager::ALERT,
1522
+
'alert_type' => 'warning',
1523
+
'heading' => esc_html__( 'Please note!', 'elementor' ),
1524
+
'content' => esc_html__( 'Custom positioning is not considered best practice for responsive web design and should not be used too frequently.', 'elementor' ),
1525
+
'render_type' => 'ui',
1526
+
'condition' => [
1527
+
'position!' => '',
1528
+
],
1529
+
]
1530
+
);
1531
+
1532
+
// TODO: Copied from `common.php` - Extract to group control.
1533
+
$this->add_control(
1534
+
'position',
1535
+
[
1536
+
'label' => esc_html__( 'Position', 'elementor' ),
1537
+
'type' => Controls_Manager::SELECT,
1538
+
'default' => '',
1539
+
'options' => [
1540
+
'' => esc_html__( 'Default', 'elementor' ),
1541
+
'absolute' => esc_html__( 'Absolute', 'elementor' ),
1542
+
'fixed' => esc_html__( 'Fixed', 'elementor' ),
1543
+
],
1544
+
'selectors' => [
1545
+
'{{WRAPPER}}' => '--position: {{VALUE}};',
1546
+
],
1547
+
'frontend_available' => true,
1548
+
'separator' => 'before',
1549
+
]
1550
+
);
1551
+
1552
+
$left = esc_html__( 'Left', 'elementor' );
1553
+
$right = esc_html__( 'Right', 'elementor' );
1554
+
1555
+
$start = is_rtl() ? $right : $left;
1556
+
$end = ! is_rtl() ? $right : $left;
1557
+
1558
+
$this->add_control(
1559
+
'_offset_orientation_h',
1560
+
[
1561
+
'label' => esc_html__( 'Horizontal Orientation', 'elementor' ),
1562
+
'type' => Controls_Manager::CHOOSE,
1563
+
'toggle' => false,
1564
+
'default' => 'start',
1565
+
'options' => [
1566
+
'start' => [
1567
+
'title' => $start,
1568
+
'icon' => 'eicon-h-align-left',
1569
+
],
1570
+
'end' => [
1571
+
'title' => $end,
1572
+
'icon' => 'eicon-h-align-right',
1573
+
],
1574
+
],
1575
+
'classes' => 'elementor-control-start-end',
1576
+
'render_type' => 'ui',
1577
+
'condition' => [
1578
+
'position!' => '',
1579
+
],
1580
+
]
1581
+
);
1582
+
1583
+
$this->add_responsive_control(
1584
+
'_offset_x',
1585
+
[
1586
+
'label' => esc_html__( 'Offset', 'elementor' ),
1587
+
'type' => Controls_Manager::SLIDER,
1588
+
'range' => [
1589
+
'px' => [
1590
+
'min' => -1000,
1591
+
'max' => 1000,
1592
+
],
1593
+
'%' => [
1594
+
'min' => -200,
1595
+
'max' => 200,
1596
+
],
1597
+
'vw' => [
1598
+
'min' => -200,
1599
+
'max' => 200,
1600
+
],
1601
+
'vh' => [
1602
+
'min' => -200,
1603
+
'max' => 200,
1604
+
],
1605
+
],
1606
+
'default' => [
1607
+
'size' => 0,
1608
+
],
1609
+
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'vh', 'custom' ],
1610
+
'selectors' => [
1611
+
'body:not(.rtl) {{WRAPPER}}' => 'left: {{SIZE}}{{UNIT}}',
1612
+
'body.rtl {{WRAPPER}}' => 'right: {{SIZE}}{{UNIT}}',
1613
+
],
1614
+
'condition' => [
1615
+
'_offset_orientation_h!' => 'end',
1616
+
'position!' => '',
1617
+
],
1618
+
]
1619
+
);
1620
+
1621
+
$this->add_responsive_control(
1622
+
'_offset_x_end',
1623
+
[
1624
+
'label' => esc_html__( 'Offset', 'elementor' ),
1625
+
'type' => Controls_Manager::SLIDER,
1626
+
'range' => [
1627
+
'px' => [
1628
+
'min' => -1000,
1629
+
'max' => 1000,
1630
+
],
1631
+
'%' => [
1632
+
'min' => -200,
1633
+
'max' => 200,
1634
+
],
1635
+
'vw' => [
1636
+
'min' => -200,
1637
+
'max' => 200,
1638
+
],
1639
+
'vh' => [
1640
+
'min' => -200,
1641
+
'max' => 200,
1642
+
],
1643
+
],
1644
+
'default' => [
1645
+
'size' => 0,
1646
+
],
1647
+
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'vh', 'custom' ],
1648
+
'selectors' => [
1649
+
'body:not(.rtl) {{WRAPPER}}' => 'right: {{SIZE}}{{UNIT}}',
1650
+
'body.rtl {{WRAPPER}}' => 'left: {{SIZE}}{{UNIT}}',
1651
+
],
1652
+
'condition' => [
1653
+
'_offset_orientation_h' => 'end',
1654
+
'position!' => '',
1655
+
],
1656
+
]
1657
+
);
1658
+
1659
+
$this->add_control(
1660
+
'_offset_orientation_v',
1661
+
[
1662
+
'label' => esc_html__( 'Vertical Orientation', 'elementor' ),
1663
+
'type' => Controls_Manager::CHOOSE,
1664
+
'toggle' => false,
1665
+
'default' => 'start',
1666
+
'options' => [
1667
+
'start' => [
1668
+
'title' => esc_html__( 'Top', 'elementor' ),
1669
+
'icon' => 'eicon-v-align-top',
1670
+
],
1671
+
'end' => [
1672
+
'title' => esc_html__( 'Bottom', 'elementor' ),
1673
+
'icon' => 'eicon-v-align-bottom',
1674
+
],
1675
+
],
1676
+
'render_type' => 'ui',
1677
+
'condition' => [
1678
+
'position!' => '',
1679
+
],
1680
+
]
1681
+
);
1682
+
1683
+
$this->add_responsive_control(
1684
+
'_offset_y',
1685
+
[
1686
+
'label' => esc_html__( 'Offset', 'elementor' ),
1687
+
'type' => Controls_Manager::SLIDER,
1688
+
'range' => [
1689
+
'px' => [
1690
+
'min' => -1000,
1691
+
'max' => 1000,
1692
+
],
1693
+
'%' => [
1694
+
'min' => -200,
1695
+
'max' => 200,
1696
+
],
1697
+
'vh' => [
1698
+
'min' => -200,
1699
+
'max' => 200,
1700
+
],
1701
+
'vw' => [
1702
+
'min' => -200,
1703
+
'max' => 200,
1704
+
],
1705
+
],
1706
+
'size_units' => [ 'px', '%', 'em', 'rem', 'vh', 'vw', 'custom' ],
1707
+
'default' => [
1708
+
'size' => 0,
1709
+
],
1710
+
'selectors' => [
1711
+
'{{WRAPPER}}' => 'top: {{SIZE}}{{UNIT}}',
1712
+
],
1713
+
'condition' => [
1714
+
'_offset_orientation_v!' => 'end',
1715
+
'position!' => '',
1716
+
],
1717
+
]
1718
+
);
1719
+
1720
+
$this->add_responsive_control(
1721
+
'_offset_y_end',
1722
+
[
1723
+
'label' => esc_html__( 'Offset', 'elementor' ),
1724
+
'type' => Controls_Manager::SLIDER,
1725
+
'range' => [
1726
+
'px' => [
1727
+
'min' => -1000,
1728
+
'max' => 1000,
1729
+
],
1730
+
'%' => [
1731
+
'min' => -200,
1732
+
'max' => 200,
1733
+
],
1734
+
'vh' => [
1735
+
'min' => -200,
1736
+
'max' => 200,
1737
+
],
1738
+
'vw' => [
1739
+
'min' => -200,
1740
+
'max' => 200,
1741
+
],
1742
+
],
1743
+
'size_units' => [ 'px', '%', 'em', 'rem', 'vh', 'vw', 'custom' ],
1744
+
'default' => [
1745
+
'size' => 0,
1746
+
],
1747
+
'selectors' => [
1748
+
'{{WRAPPER}}' => 'bottom: {{SIZE}}{{UNIT}}',
1749
+
],
1750
+
'condition' => [
1751
+
'_offset_orientation_v' => 'end',
1752
+
'position!' => '',
1753
+
],
1754
+
]
1755
+
);
1756
+
1757
+
$this->add_responsive_control(
1758
+
'z_index',
1759
+
[
1760
+
'label' => esc_html__( 'Z-Index', 'elementor' ),
1761
+
'type' => Controls_Manager::NUMBER,
1762
+
'min' => 0,
1763
+
'selectors' => [
1764
+
'{{WRAPPER}}' => '--z-index: {{VALUE}};',
1765
+
],
1766
+
]
1767
+
);
1768
+
1769
+
$this->add_control(
1770
+
'_element_id',
1771
+
[
1772
+
'label' => esc_html__( 'CSS ID', 'elementor' ),
1773
+
'type' => Controls_Manager::TEXT,
1774
+
'default' => '',
1775
+
'ai' => [
1776
+
'active' => false,
1777
+
],
1778
+
'dynamic' => [
1779
+
'active' => true,
1780
+
],
1781
+
'title' => esc_html__( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'elementor' ),
1782
+
'style_transfer' => false,
1783
+
'classes' => 'elementor-control-direction-ltr',
1784
+
]
1785
+
);
1786
+
1787
+
$this->add_control(
1788
+
'css_classes',
1789
+
[
1790
+
'label' => esc_html__( 'CSS Classes', 'elementor' ),
1791
+
'type' => Controls_Manager::TEXT,
1792
+
'default' => '',
1793
+
'ai' => [
1794
+
'active' => false,
1795
+
],
1796
+
'dynamic' => [
1797
+
'active' => true,
1798
+
],
1799
+
'prefix_class' => '',
1800
+
'title' => esc_html__( 'Add your custom class WITHOUT the dot. e.g: my-class', 'elementor' ),
1801
+
'classes' => 'elementor-control-direction-ltr',
1802
+
]
1803
+
);
1804
+
1805
+
Plugin::$instance->controls_manager->add_display_conditions_controls( $this );
1806
+
1807
+
$this->end_controls_section();
1808
+
}
1809
+
1810
+
/**
1811
+
* Register the Container's motion effects controls.
1812
+
*
1813
+
* @return void
1814
+
*/
1815
+
protected function register_motion_effects_controls() {
1816
+
$this->start_controls_section(
1817
+
'section_effects',
1818
+
[
1819
+
'label' => esc_html__( 'Motion Effects', 'elementor' ),
1820
+
'tab' => Controls_Manager::TAB_ADVANCED,
1821
+
]
1822
+
);
1823
+
1824
+
Plugin::$instance->controls_manager->add_motion_effects_promotion_control( $this );
1825
+
1826
+
$this->add_responsive_control(
1827
+
'animation',
1828
+
[
1829
+
'label' => esc_html__( 'Entrance Animation', 'elementor' ),
1830
+
'type' => Controls_Manager::ANIMATION,
1831
+
'frontend_available' => true,
1832
+
]
1833
+
);
1834
+
1835
+
$this->add_control(
1836
+
'animation_duration',
1837
+
[
1838
+
'label' => esc_html__( 'Animation Duration', 'elementor' ),
1839
+
'type' => Controls_Manager::SELECT,
1840
+
'default' => '',
1841
+
'options' => [
1842
+
'slow' => esc_html__( 'Slow', 'elementor' ),
1843
+
'' => esc_html__( 'Normal', 'elementor' ),
1844
+
'fast' => esc_html__( 'Fast', 'elementor' ),
1845
+
],
1846
+
'prefix_class' => 'animated-',
1847
+
'condition' => [
1848
+
'animation!' => '',
1849
+
],
1850
+
]
1851
+
);
1852
+
1853
+
$this->add_control(
1854
+
'animation_delay',
1855
+
[
1856
+
'label' => esc_html__( 'Animation Delay', 'elementor' ) . ' (ms)',
1857
+
'type' => Controls_Manager::NUMBER,
1858
+
'default' => '',
1859
+
'min' => 0,
1860
+
'step' => 100,
1861
+
'condition' => [
1862
+
'animation!' => '',
1863
+
],
1864
+
'render_type' => 'none',
1865
+
'frontend_available' => true,
1866
+
]
1867
+
);
1868
+
1869
+
$this->end_controls_section();
1870
+
}
1871
+
1872
+
/**
1873
+
* Register the Container's responsive controls.
1874
+
*
1875
+
* @return void
1876
+
*/
1877
+
protected function register_responsive_controls() {
1878
+
$this->start_controls_section(
1879
+
'_section_responsive',
1880
+
[
1881
+
'label' => esc_html__( 'Responsive', 'elementor' ),
1882
+
'tab' => Controls_Manager::TAB_ADVANCED,
1883
+
]
1884
+
);
1885
+
1886
+
$this->add_control(
1887
+
'heading_visibility',
1888
+
[
1889
+
'label' => esc_html__( 'Visibility', 'elementor' ),
1890
+
'type' => Controls_Manager::HEADING,
1891
+
]
1892
+
);
1893
+
1894
+
$this->add_control(
1895
+
'responsive_description',
1896
+
[
1897
+
'raw' => sprintf(
1898
+
/* translators: 1: Link open tag, 2: Link close tag. */
1899
+
esc_html__( 'Responsive visibility will take effect only on %1$s preview mode %2$s or live page, and not while editing in Elementor.', 'elementor' ),
1900
+
'<a href="javascript: $e.run( \'panel/close\' )">',
1901
+
'</a>'
1902
+
),
1903
+
'type' => Controls_Manager::RAW_HTML,
1904
+
'content_classes' => 'elementor-descriptor',
1905
+
]
1906
+
);
1907
+
1908
+
$this->add_hidden_device_controls();
1909
+
1910
+
$this->end_controls_section();
1911
+
}
1912
+
1913
+
/**
1914
+
* Register the Container's advanced tab.
1915
+
*
1916
+
* @return void
1917
+
*/
1918
+
protected function register_advanced_tab() {
1919
+
$this->register_advanced_controls();
1920
+
1921
+
$this->register_motion_effects_controls();
1922
+
1923
+
$this->hook_sticky_notice_into_transform_section();
1924
+
1925
+
$this->register_transform_section( 'con' );
1926
+
1927
+
$this->register_responsive_controls();
1928
+
1929
+
Plugin::$instance->controls_manager->add_custom_attributes_controls( $this );
1930
+
1931
+
Plugin::$instance->controls_manager->add_custom_css_controls( $this );
1932
+
}
1933
+
1934
+
protected function hook_sticky_notice_into_transform_section() {
1935
+
add_action( 'elementor/element/container/_section_transform/after_section_start', function( Container $container ) {
1936
+
if ( ! empty( $container->get_controls( 'transform_sticky_notice' ) ) ) {
1937
+
return;
1938
+
}
1939
+
1940
+
$container->add_control(
1941
+
'transform_sticky_notice',
1942
+
[
1943
+
'type' => Controls_Manager::ALERT,
1944
+
'alert_type' => 'warning',
1945
+
'content' => esc_html__( 'Note: Avoid applying transform properties on sticky containers. Doing so might cause unexpected results.', 'elementor' ),
1946
+
]
1947
+
);
1948
+
} );
1949
+
}
1950
+
1951
+
/**
1952
+
* Register the Container's controls.
1953
+
*
1954
+
* @return void
1955
+
*/
1956
+
protected function register_controls() {
1957
+
$this->register_layout_tab();
1958
+
$this->register_style_tab();
1959
+
$this->register_advanced_tab();
1960
+
}
1961
+
1962
+
public function on_import( $element ) {
1963
+
return self::slider_to_gaps_converter( $element );
1964
+
}
1965
+
1966
+
/**
1967
+
* Convert slider to gaps control for the 3.16 upgrade script
1968
+
*
1969
+
* @param array $element
1970
+
* @return array
1971
+
*/
1972
+
public static function slider_to_gaps_converter( $element ) {
1973
+
$breakpoints = array_keys( (array) Plugin::$instance->breakpoints->get_breakpoints() );
1974
+
$breakpoints[] = 'desktop';
1975
+
$control_name = 'flex_gap';
1976
+
1977
+
foreach ( $breakpoints as $breakpoint ) {
1978
+
$control = 'desktop' !== $breakpoint
1979
+
? $control_name . '_' . $breakpoint
1980
+
: $control_name;
1981
+
1982
+
if ( ! isset( $element['settings'][ $control ] ) ) {
1983
+
continue;
1984
+
}
1985
+
1986
+
$already_using_gaps_control = isset( $element['settings'][ $control ]['isLinked'] ); // Slider control won't have the 'isLinked' property.
1987
+
1988
+
if ( ! $already_using_gaps_control ) {
1989
+
$old_size = strval( $element['settings'][ $control ]['size'] );
1990
+
1991
+
$element['settings'][ $control ]['column'] = $old_size;
1992
+
$element['settings'][ $control ]['row'] = $old_size;
1993
+
$element['settings'][ $control ]['isLinked'] = true;
1994
+
}
1995
+
}
1996
+
1997
+
return $element;
1998
+
}
1999
+
}
2000
+