PluginProbe
Elementor Website Builder – more than just a page builder / 3.6.0-dev1
Elementor Website Builder – more than just a page builder v3.6.0-dev1
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 / trunk / includes / widgets / common.php

common.php in Elementor Website Builder – more than just a page builder 3.6.0-dev1, at trunk/includes/widgets/common.php

1,672 lines 40.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor;
3
4 use Elementor\Core\Breakpoints\Manager as Breakpoints_Manager;
5
6 if ( ! defined( 'ABSPATH' ) ) {
7 exit; // Exit if accessed directly.
8 }
9
10 /**
11 * Elementor common widget.
12 *
13 * Elementor base widget that gives you all the advanced options of the basic
14 * widget.
15 *
16 * @since 1.0.0
17 */
18 class Widget_Common extends Widget_Base {
19
20 /**
21 * Get widget name.
22 *
23 * Retrieve common widget name.
24 *
25 * @since 1.0.0
26 * @access public
27 *
28 * @return string Widget name.
29 */
30 public function get_name() {
31 return 'common';
32 }
33
34 /**
35 * Show in panel.
36 *
37 * Whether to show the common widget in the panel or not.
38 *
39 * @since 1.0.0
40 * @access public
41 *
42 * @return bool Whether to show the widget in the panel.
43 */
44 public function show_in_panel() {
45 return false;
46 }
47
48 /**
49 * Get Responsive Device Args
50 *
51 * Receives an array of device args, and duplicates it for each active breakpoint.
52 * Returns an array of device args.
53 *
54 * @since 3.4.7
55 * @access protected
56 *
57 * @param array $args arguments to duplicate per breakpoint
58 * @param array $devices_to_exclude
59 *
60 * @return array responsive device args
61 */
62 protected function get_responsive_device_args( array $args, array $devices_to_exclude = [] ) {
63 $device_args = [];
64 $breakpoints = Breakpoints_Manager::get_default_config();
65
66 foreach ( $breakpoints as $breakpoint_key => $breakpoint ) {
67 // If the device is not excluded, add it to the device args array.
68 if ( ! in_array( $breakpoint_key, $devices_to_exclude, true ) ) {
69 $parsed_device_args = $this->parse_device_args_placeholders( $args, $breakpoint_key );
70
71 $device_args[ $breakpoint_key ] = $parsed_device_args;
72 }
73 }
74
75 return $device_args;
76 }
77
78 /**
79 * Parse Device Args Placeholders
80 *
81 * Receives an array of args. Iterates over the args, and replaces the {{DEVICE}} placeholder, if exists, with the
82 * passed breakpoint key.
83 *
84 * @since 3.4.7
85 * @access private
86 *
87 * @param array $args
88 * @param string $breakpoint_key
89 * @return array parsed device args
90 */
91 private function parse_device_args_placeholders( array $args, $breakpoint_key ) {
92 $parsed_args = [];
93
94 foreach ( $args as $arg_key => $arg_value ) {
95 $arg_key = str_replace( '{{DEVICE}}', $breakpoint_key, $arg_key );
96
97 if ( is_array( $arg_value ) ) {
98 $arg_value = $this->parse_device_args_placeholders( $arg_value, $breakpoint_key );
99 }
100
101 $parsed_args[ $arg_key ] = $arg_value;
102 }
103
104 return $parsed_args;
105 }
106
107 /**
108 * @param $shape String Shape name.
109 *
110 * @return string The shape path in the assets folder.
111 */
112 private function get_shape_url( $shape ) {
113 return ELEMENTOR_ASSETS_URL . 'mask-shapes/' . $shape . '.svg';
114 }
115
116 /**
117 * Return a translated user-friendly list of the available masking shapes.
118 *
119 * @param bool $add_custom Determine if the output should contain `Custom` options.
120 *
121 * @return array Array of shapes with their URL as key.
122 */
123 private function get_shapes( $add_custom = true ) {
124 $shapes = [
125 'circle' => esc_html__( 'Circle', 'elementor' ),
126 'flower' => esc_html__( 'Flower', 'elementor' ),
127 'sketch' => esc_html__( 'Sketch', 'elementor' ),
128 'triangle' => esc_html__( 'Triangle', 'elementor' ),
129 'blob' => esc_html__( 'Blob', 'elementor' ),
130 'hexagon' => esc_html__( 'Hexagon', 'elementor' ),
131 ];
132
133 if ( $add_custom ) {
134 $shapes['custom'] = esc_html__( 'Custom', 'elementor' );
135 }
136
137 return $shapes;
138 }
139
140 /**
141 * Gets a string of CSS rules to apply, and returns an array of selectors with those rules.
142 * This function has been created in order to deal with masking for image widget.
143 * For most of the widgets the mask is being applied to the wrapper itself, but in the case of an image widget,
144 * the `img` tag should be masked directly. So instead of writing a lot of selectors every time,
145 * this function builds both of those selectors easily.
146 *
147 * @param $rules string The CSS rules to apply.
148 *
149 * @return array Selectors with the rules applied.
150 */
151 private function get_mask_selectors( $rules ) {
152 $mask_selectors = [
153 'default' => '{{WRAPPER}}:not( .elementor-widget-image ) .elementor-widget-container',
154 'image' => '{{WRAPPER}}.elementor-widget-image .elementor-widget-container img',
155 ];
156
157 return [
158 $mask_selectors['default'] => $rules,
159 $mask_selectors['image'] => $rules,
160 ];
161 }
162
163 /**
164 * Register the Layout section.
165 *
166 * @return void
167 */
168 private function register_layout_section() {
169 $this->start_controls_section(
170 '_section_style',
171 [
172 'label' => esc_html__( 'Layout', 'elementor' ),
173 'tab' => Controls_Manager::TAB_ADVANCED,
174 ]
175 );
176
177 // Element Name for the Navigator
178 $this->add_control(
179 '_title',
180 [
181 'label' => esc_html__( 'Title', 'elementor' ),
182 'type' => Controls_Manager::HIDDEN,
183 'render_type' => 'none',
184 ]
185 );
186
187 $this->add_responsive_control(
188 '_margin',
189 [
190 'label' => esc_html__( 'Margin', 'elementor' ),
191 'type' => Controls_Manager::DIMENSIONS,
192 'size_units' => [ 'px', 'em', '%', 'rem' ],
193 'selectors' => [
194 '{{WRAPPER}} > .elementor-widget-container' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
195 ],
196 ]
197 );
198
199 $this->add_responsive_control(
200 '_padding',
201 [
202 'label' => esc_html__( 'Padding', 'elementor' ),
203 'type' => Controls_Manager::DIMENSIONS,
204 'size_units' => [ 'px', 'em', '%', 'rem' ],
205 'selectors' => [
206 '{{WRAPPER}} > .elementor-widget-container' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
207 ],
208 ]
209 );
210
211 $experiments_manager = Plugin::$instance->experiments;
212 $is_container_active = $experiments_manager->is_feature_active( 'container' );
213
214 // TODO: For BC - Remove in the future.
215 $this->add_responsive_control(
216 '_element_width',
217 [
218 'label' => esc_html__( 'Width', 'elementor' ),
219 'type' => Controls_Manager::SELECT,
220 'default' => '',
221 'options' => [
222 '' => esc_html__( 'Default', 'elementor' ),
223 'inherit' => esc_html__( 'Full Width', 'elementor' ) . ' (100%)',
224 'auto' => esc_html__( 'Inline', 'elementor' ) . ' (auto)',
225 'initial' => esc_html__( 'Custom', 'elementor' ),
226 ],
227 'selectors_dictionary' => [
228 'inherit' => '100%',
229 ],
230 'condition' => $is_container_active ? [ '_element_width!' => '' ] : [], // TODO: For BC.
231 'prefix_class' => 'elementor-widget%s__width-',
232 'selectors' => [
233 '{{WRAPPER}}' => 'width: {{VALUE}}; max-width: {{VALUE}}',
234 ],
235 ]
236 );
237
238 $this->add_responsive_control(
239 '_element_custom_width',
240 [
241 'label' => esc_html__( 'Width', 'elementor' ),
242 'type' => Controls_Manager::SLIDER,
243 'default' => [
244 'unit' => '%',
245 ],
246 'range' => [
247 'px' => [
248 'max' => 1000,
249 'step' => 1,
250 ],
251 '%' => [
252 'max' => 100,
253 'step' => 1,
254 ],
255 ],
256 'size_units' => [ 'px', '%', 'vw' ],
257 'selectors' => [
258 '{{WRAPPER}}' => 'width: {{SIZE}}{{UNIT}}; max-width: {{SIZE}}{{UNIT}}',
259 ],
260 'separator' => 'after',
261 // TODO: BC settings:
262 'condition' => $is_container_active ? [] : [ '_element_width' => 'initial' ],
263 'device_args' => $is_container_active
264 ? []
265 : $this->get_responsive_device_args( [
266 'condition' => [
267 '_element_width_{{DEVICE}}' => [ 'initial' ],
268 ],
269 ] ),
270 ]
271 );
272
273 // Register Flex controls only if the Container experiment is active.
274 if ( $is_container_active ) {
275 $this->add_group_control(
276 Group_Control_Flex_Item::get_type(),
277 [
278 'name' => '_flex',
279 // Hack to increase specificity and make sure that the current widget overrides the
280 // parent flex settings.
281 'selector' => '{{WRAPPER}}.elementor-element',
282 'include' => [
283 'align_self',
284 'order',
285 'order_custom',
286 'size',
287 'grow',
288 'shrink',
289 ],
290 ]
291 );
292 }
293
294 $vertical_align_conditions = [
295 '_element_width!' => '',
296 '_position' => '',
297 ];
298
299 if ( $is_container_active ) {
300 $vertical_align_conditions['_element_vertical_align!'] = ''; // TODO: For BC.
301 }
302
303 // TODO: For BC - Remove in the future.
304 $this->add_responsive_control(
305 '_element_vertical_align',
306 [
307 'label' => esc_html__( 'Vertical Align', 'elementor' ),
308 'type' => Controls_Manager::CHOOSE,
309 'options' => [
310 'flex-start' => [
311 'title' => esc_html__( 'Start', 'elementor' ),
312 'icon' => 'eicon-v-align-top',
313 ],
314 'center' => [
315 'title' => esc_html__( 'Center', 'elementor' ),
316 'icon' => 'eicon-v-align-middle',
317 ],
318 'flex-end' => [
319 'title' => esc_html__( 'End', 'elementor' ),
320 'icon' => 'eicon-v-align-bottom',
321 ],
322 ],
323 'condition' => $vertical_align_conditions,
324 'selectors' => [
325 '{{WRAPPER}}' => 'align-self: {{VALUE}}',
326 ],
327 ]
328 );
329
330 $this->add_control(
331 '_position_description',
332 [
333 'raw' => '<strong>' . esc_html__( 'Please note!', 'elementor' ) . '</strong> ' . esc_html__( 'Custom positioning is not considered best practice for responsive web design and should not be used too frequently.', 'elementor' ),
334 'type' => Controls_Manager::RAW_HTML,
335 'content_classes' => 'elementor-panel-alert elementor-panel-alert-warning',
336 'render_type' => 'ui',
337 'condition' => [
338 '_position!' => '',
339 ],
340 ]
341 );
342
343 $this->add_control(
344 '_position',
345 [
346 'label' => esc_html__( 'Position', 'elementor' ),
347 'type' => Controls_Manager::SELECT,
348 'default' => '',
349 'options' => [
350 '' => esc_html__( 'Default', 'elementor' ),
351 'absolute' => esc_html__( 'Absolute', 'elementor' ),
352 'fixed' => esc_html__( 'Fixed', 'elementor' ),
353 ],
354 'prefix_class' => 'elementor-',
355 'frontend_available' => true,
356 'separator' => 'before',
357 ]
358 );
359
360 $start = is_rtl() ? esc_html__( 'Right', 'elementor' ) : esc_html__( 'Left', 'elementor' );
361 $end = ! is_rtl() ? esc_html__( 'Right', 'elementor' ) : esc_html__( 'Left', 'elementor' );
362
363 $this->add_control(
364 '_offset_orientation_h',
365 [
366 'label' => esc_html__( 'Horizontal Orientation', 'elementor' ),
367 'type' => Controls_Manager::CHOOSE,
368 'toggle' => false,
369 'default' => 'start',
370 'options' => [
371 'start' => [
372 'title' => $start,
373 'icon' => 'eicon-h-align-left',
374 ],
375 'end' => [
376 'title' => $end,
377 'icon' => 'eicon-h-align-right',
378 ],
379 ],
380 'classes' => 'elementor-control-start-end',
381 'render_type' => 'ui',
382 'condition' => [
383 '_position!' => '',
384 ],
385 ]
386 );
387
388 $this->add_responsive_control(
389 '_offset_x',
390 [
391 'label' => esc_html__( 'Offset', 'elementor' ),
392 'type' => Controls_Manager::SLIDER,
393 'range' => [
394 'px' => [
395 'min' => -1000,
396 'max' => 1000,
397 'step' => 1,
398 ],
399 '%' => [
400 'min' => -200,
401 'max' => 200,
402 ],
403 'vw' => [
404 'min' => -200,
405 'max' => 200,
406 ],
407 'vh' => [
408 'min' => -200,
409 'max' => 200,
410 ],
411 ],
412 'default' => [
413 'size' => '0',
414 ],
415 'size_units' => [ 'px', '%', 'vw', 'vh' ],
416 'selectors' => [
417 'body:not(.rtl) {{WRAPPER}}' => 'left: {{SIZE}}{{UNIT}}',
418 'body.rtl {{WRAPPER}}' => 'right: {{SIZE}}{{UNIT}}',
419 ],
420 'condition' => [
421 '_offset_orientation_h!' => 'end',
422 '_position!' => '',
423 ],
424 ]
425 );
426
427 $this->add_responsive_control(
428 '_offset_x_end',
429 [
430 'label' => esc_html__( 'Offset', 'elementor' ),
431 'type' => Controls_Manager::SLIDER,
432 'range' => [
433 'px' => [
434 'min' => -1000,
435 'max' => 1000,
436 'step' => 0.1,
437 ],
438 '%' => [
439 'min' => -200,
440 'max' => 200,
441 ],
442 'vw' => [
443 'min' => -200,
444 'max' => 200,
445 ],
446 'vh' => [
447 'min' => -200,
448 'max' => 200,
449 ],
450 ],
451 'default' => [
452 'size' => '0',
453 ],
454 'size_units' => [ 'px', '%', 'vw', 'vh' ],
455 'selectors' => [
456 'body:not(.rtl) {{WRAPPER}}' => 'right: {{SIZE}}{{UNIT}}',
457 'body.rtl {{WRAPPER}}' => 'left: {{SIZE}}{{UNIT}}',
458 ],
459 'condition' => [
460 '_offset_orientation_h' => 'end',
461 '_position!' => '',
462 ],
463 ]
464 );
465
466 $this->add_control(
467 '_offset_orientation_v',
468 [
469 'label' => esc_html__( 'Vertical Orientation', 'elementor' ),
470 'type' => Controls_Manager::CHOOSE,
471 'toggle' => false,
472 'default' => 'start',
473 'options' => [
474 'start' => [
475 'title' => esc_html__( 'Top', 'elementor' ),
476 'icon' => 'eicon-v-align-top',
477 ],
478 'end' => [
479 'title' => esc_html__( 'Bottom', 'elementor' ),
480 'icon' => 'eicon-v-align-bottom',
481 ],
482 ],
483 'render_type' => 'ui',
484 'condition' => [
485 '_position!' => '',
486 ],
487 ]
488 );
489
490 $this->add_responsive_control(
491 '_offset_y',
492 [
493 'label' => esc_html__( 'Offset', 'elementor' ),
494 'type' => Controls_Manager::SLIDER,
495 'range' => [
496 'px' => [
497 'min' => -1000,
498 'max' => 1000,
499 'step' => 1,
500 ],
501 '%' => [
502 'min' => -200,
503 'max' => 200,
504 ],
505 'vh' => [
506 'min' => -200,
507 'max' => 200,
508 ],
509 'vw' => [
510 'min' => -200,
511 'max' => 200,
512 ],
513 ],
514 'size_units' => [ 'px', '%', 'vh', 'vw' ],
515 'default' => [
516 'size' => '0',
517 ],
518 'selectors' => [
519 '{{WRAPPER}}' => 'top: {{SIZE}}{{UNIT}}',
520 ],
521 'condition' => [
522 '_offset_orientation_v!' => 'end',
523 '_position!' => '',
524 ],
525 ]
526 );
527
528 $this->add_responsive_control(
529 '_offset_y_end',
530 [
531 'label' => esc_html__( 'Offset', 'elementor' ),
532 'type' => Controls_Manager::SLIDER,
533 'range' => [
534 'px' => [
535 'min' => -1000,
536 'max' => 1000,
537 'step' => 1,
538 ],
539 '%' => [
540 'min' => -200,
541 'max' => 200,
542 ],
543 'vh' => [
544 'min' => -200,
545 'max' => 200,
546 ],
547 'vw' => [
548 'min' => -200,
549 'max' => 200,
550 ],
551 ],
552 'size_units' => [ 'px', '%', 'vh', 'vw' ],
553 'default' => [
554 'size' => '0',
555 ],
556 'selectors' => [
557 '{{WRAPPER}}' => 'bottom: {{SIZE}}{{UNIT}}',
558 ],
559 'condition' => [
560 '_offset_orientation_v' => 'end',
561 '_position!' => '',
562 ],
563 ]
564 );
565
566 $this->add_responsive_control(
567 '_z_index',
568 [
569 'label' => esc_html__( 'Z-Index', 'elementor' ),
570 'type' => Controls_Manager::NUMBER,
571 'selectors' => [
572 '{{WRAPPER}}' => 'z-index: {{VALUE}};',
573 ],
574 ]
575 );
576
577 $this->add_control(
578 '_element_id',
579 [
580 'label' => esc_html__( 'CSS ID', 'elementor' ),
581 'type' => Controls_Manager::TEXT,
582 'dynamic' => [
583 'active' => true,
584 ],
585 'default' => '',
586 'title' => esc_html__( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'elementor' ),
587 'style_transfer' => false,
588 'classes' => 'elementor-control-direction-ltr',
589 ]
590 );
591
592 $this->add_control(
593 '_css_classes',
594 [
595 'label' => esc_html__( 'CSS Classes', 'elementor' ),
596 'type' => Controls_Manager::TEXT,
597 'dynamic' => [
598 'active' => true,
599 ],
600 'prefix_class' => '',
601 'title' => esc_html__( 'Add your custom class WITHOUT the dot. e.g: my-class', 'elementor' ),
602 'classes' => 'elementor-control-direction-ltr',
603 ]
604 );
605
606 $this->end_controls_section();
607 }
608
609 /**
610 * Register the Motion Effects section.
611 *
612 * @return void
613 */
614 private function register_effects_section() {
615 $this->start_controls_section(
616 'section_effects',
617 [
618 'label' => esc_html__( 'Motion Effects', 'elementor' ),
619 'tab' => Controls_Manager::TAB_ADVANCED,
620 ]
621 );
622
623 $this->add_responsive_control(
624 '_animation',
625 [
626 'label' => esc_html__( 'Entrance Animation', 'elementor' ),
627 'type' => Controls_Manager::ANIMATION,
628 'frontend_available' => true,
629 ]
630 );
631
632 $this->add_control(
633 'animation_duration',
634 [
635 'label' => esc_html__( 'Animation Duration', 'elementor' ),
636 'type' => Controls_Manager::SELECT,
637 'default' => '',
638 'options' => [
639 'slow' => esc_html__( 'Slow', 'elementor' ),
640 '' => esc_html__( 'Normal', 'elementor' ),
641 'fast' => esc_html__( 'Fast', 'elementor' ),
642 ],
643 'prefix_class' => 'animated-',
644 'condition' => [
645 '_animation!' => '',
646 ],
647 ]
648 );
649
650 $this->add_control(
651 '_animation_delay',
652 [
653 'label' => esc_html__( 'Animation Delay', 'elementor' ) . ' (ms)',
654 'type' => Controls_Manager::NUMBER,
655 'default' => '',
656 'min' => 0,
657 'step' => 100,
658 'condition' => [
659 '_animation!' => '',
660 ],
661 'render_type' => 'none',
662 'frontend_available' => true,
663 ]
664 );
665
666 $this->end_controls_section();
667 }
668
669 private function register_transform_section() {
670 $this->start_controls_section(
671 '_section_transform',
672 [
673 'label' => esc_html__( 'Transform', 'elementor' ),
674 'tab' => Controls_Manager::TAB_ADVANCED,
675 ]
676 );
677
678 $this->start_controls_tabs( '_tabs_positioning' );
679
680 $transform_prefix_class = 'e-';
681 $transform_return_value = 'transform';
682
683 foreach ( [ '', '_hover' ] as $tab ) {
684 $state = '_hover' === $tab ? ':hover' : '';
685
686 $this->start_controls_tab(
687 "_tab_positioning{$tab}",
688 [
689 'label' => '' === $tab ? esc_html__( 'Normal', 'elementor' ) : esc_html__( 'Hover', 'elementor' ),
690 ]
691 );
692
693 $this->add_control(
694 "_transform_rotate_popover{$tab}",
695 [
696 'label' => esc_html__( 'Rotate', 'elementor' ),
697 'type' => Controls_Manager::POPOVER_TOGGLE,
698 'prefix_class' => $transform_prefix_class,
699 'return_value' => $transform_return_value,
700 ]
701 );
702
703 $this->start_popover();
704
705 $this->add_responsive_control(
706 "_transform_rotateZ_effect{$tab}",
707 [
708 'label' => esc_html__( 'Rotate', 'elementor' ),
709 'type' => Controls_Manager::SLIDER,
710 'range' => [
711 'px' => [
712 'min' => -360,
713 'max' => 360,
714 ],
715 ],
716 'selectors' => [
717 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-rotateZ: {{SIZE}}deg',
718 ],
719 'condition' => [
720 "_transform_rotate_popover{$tab}!" => '',
721 ],
722 'frontend_available' => true,
723 ]
724 );
725
726 $this->add_control(
727 "_transform_rotate_3d{$tab}",
728 [
729 'label' => esc_html__( '3D Rotate', 'elementor' ),
730 'type' => Controls_Manager::SWITCHER,
731 'label_on' => esc_html__( 'On', 'elementor' ),
732 'label_off' => esc_html__( 'Off', 'elementor' ),
733 'selectors' => [
734 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-rotateX: 1deg; --e-transform-perspective: 20px;',
735 ],
736 'condition' => [
737 "_transform_rotate_popover{$tab}!" => '',
738 ],
739 ]
740 );
741
742 $this->add_responsive_control(
743 "_transform_rotateX_effect{$tab}",
744 [
745 'label' => esc_html__( 'Rotate X', 'elementor' ),
746 'type' => Controls_Manager::SLIDER,
747 'range' => [
748 'px' => [
749 'min' => -360,
750 'max' => 360,
751 ],
752 ],
753 'condition' => [
754 "_transform_rotate_3d{$tab}!" => '',
755 "_transform_rotate_popover{$tab}!" => '',
756 ],
757 'selectors' => [
758 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-rotateX: {{SIZE}}deg;',
759 ],
760 'frontend_available' => true,
761 ]
762 );
763
764 $this->add_responsive_control(
765 "_transform_rotateY_effect{$tab}",
766 [
767 'label' => esc_html__( 'Rotate Y', 'elementor' ),
768 'type' => Controls_Manager::SLIDER,
769 'range' => [
770 'px' => [
771 'min' => -360,
772 'max' => 360,
773 ],
774 ],
775 'condition' => [
776 "_transform_rotate_3d{$tab}!" => '',
777 "_transform_rotate_popover{$tab}!" => '',
778 ],
779 'selectors' => [
780 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-rotateY: {{SIZE}}deg;',
781 ],
782 'frontend_available' => true,
783 ]
784 );
785
786 $this->add_responsive_control(
787 "_transform_perspective_effect{$tab}",
788 [
789 'label' => esc_html__( 'Perspective', 'elementor' ),
790 'type' => Controls_Manager::SLIDER,
791 'range' => [
792 'px' => [
793 'min' => 0,
794 'max' => 1000,
795 ],
796 ],
797 'condition' => [
798 "_transform_rotate_popover{$tab}!" => '',
799 "_transform_rotate_3d{$tab}!" => '',
800 ],
801 'selectors' => [
802 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-perspective: {{SIZE}}px',
803 ],
804 'frontend_available' => true,
805 ]
806 );
807
808 $this->end_popover();
809
810 $this->add_control(
811 "_transform_translate_popover{$tab}",
812 [
813 'label' => esc_html__( 'Offset', 'elementor' ),
814 'type' => Controls_Manager::POPOVER_TOGGLE,
815 'prefix_class' => $transform_prefix_class,
816 'return_value' => $transform_return_value,
817 ]
818 );
819
820 $this->start_popover();
821
822 $this->add_responsive_control(
823 "_transform_translateX_effect{$tab}",
824 [
825 'label' => esc_html__( 'Offset X', 'elementor' ),
826 'type' => Controls_Manager::SLIDER,
827 'size_units' => [ '%', 'px' ],
828 'range' => [
829 '%' => [
830 'min' => -100,
831 'max' => 100,
832 ],
833 'px' => [
834 'min' => -1000,
835 'max' => 1000,
836 ],
837 ],
838 'condition' => [
839 "_transform_translate_popover{$tab}!" => '',
840 ],
841 'selectors' => [
842 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-translateX: {{SIZE}}{{UNIT}};',
843 ],
844 'frontend_available' => true,
845 ]
846 );
847
848 $this->add_responsive_control(
849 "_transform_translateY_effect{$tab}",
850 [
851 'label' => esc_html__( 'Offset Y', 'elementor' ),
852 'type' => Controls_Manager::SLIDER,
853 'size_units' => [ '%', 'px' ],
854 'range' => [
855 '%' => [
856 'min' => -100,
857 'max' => 100,
858 ],
859 'px' => [
860 'min' => -1000,
861 'max' => 1000,
862 ],
863 ],
864 'condition' => [
865 "_transform_translate_popover{$tab}!" => '',
866 ],
867 'selectors' => [
868 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-translateY: {{SIZE}}{{UNIT}};',
869 ],
870 'frontend_available' => true,
871 ]
872 );
873
874 $this->end_popover();
875
876 $this->add_control(
877 "_transform_scale_popover{$tab}",
878 [
879 'label' => esc_html__( 'Scale', 'elementor' ),
880 'type' => Controls_Manager::POPOVER_TOGGLE,
881 'prefix_class' => $transform_prefix_class,
882 'return_value' => $transform_return_value,
883 ]
884 );
885
886 $this->start_popover();
887
888 $this->add_control(
889 "_transform_keep_proportions{$tab}",
890 [
891 'label' => esc_html__( 'Keep Proportions', 'elementor' ),
892 'type' => Controls_Manager::SWITCHER,
893 'label_on' => esc_html__( 'On', 'elementor' ),
894 'label_off' => esc_html__( 'Off', 'elementor' ),
895 'default' => 'yes',
896 ]
897 );
898
899 $this->add_responsive_control(
900 "_transform_scale_effect{$tab}",
901 [
902 'label' => esc_html__( 'Scale', 'elementor' ),
903 'type' => Controls_Manager::SLIDER,
904 'range' => [
905 'px' => [
906 'min' => 0,
907 'max' => 2,
908 'step' => 0.1,
909 ],
910 ],
911 'condition' => [
912 "_transform_scale_popover{$tab}!" => '',
913 "_transform_keep_proportions{$tab}!" => '',
914 ],
915 'selectors' => [
916 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-scale: {{SIZE}};',
917 ],
918 'frontend_available' => true,
919 ]
920 );
921
922 $this->add_responsive_control(
923 "_transform_scaleX_effect{$tab}",
924 [
925 'label' => esc_html__( 'Scale X', 'elementor' ),
926 'type' => Controls_Manager::SLIDER,
927 'range' => [
928 'px' => [
929 'min' => 0,
930 'max' => 2,
931 'step' => 0.1,
932 ],
933 ],
934 'condition' => [
935 "_transform_scale_popover{$tab}!" => '',
936 "_transform_keep_proportions{$tab}" => '',
937 ],
938 'selectors' => [
939 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-scaleX: {{SIZE}};',
940 ],
941 'frontend_available' => true,
942 ]
943 );
944
945 $this->add_responsive_control(
946 "_transform_scaleY_effect{$tab}",
947 [
948 'label' => esc_html__( 'Scale Y', 'elementor' ),
949 'type' => Controls_Manager::SLIDER,
950 'range' => [
951 'px' => [
952 'min' => 0,
953 'max' => 2,
954 'step' => 0.1,
955 ],
956 ],
957 'condition' => [
958 "_transform_scale_popover{$tab}!" => '',
959 "_transform_keep_proportions{$tab}" => '',
960 ],
961 'selectors' => [
962 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-scaleY: {{SIZE}};',
963 ],
964 'frontend_available' => true,
965 ]
966 );
967
968 $this->end_popover();
969
970 $this->add_control(
971 "_transform_skew_popover{$tab}",
972 [
973 'label' => esc_html__( 'Skew', 'elementor' ),
974 'type' => Controls_Manager::POPOVER_TOGGLE,
975 'prefix_class' => $transform_prefix_class,
976 'return_value' => $transform_return_value,
977 ]
978 );
979
980 $this->start_popover();
981
982 $this->add_responsive_control(
983 "_transform_skewX_effect{$tab}",
984 [
985 'label' => esc_html__( 'Skew X', 'elementor' ),
986 'type' => Controls_Manager::SLIDER,
987 'range' => [
988 'px' => [
989 'min' => -360,
990 'max' => 360,
991 ],
992 ],
993 'condition' => [
994 "_transform_skew_popover{$tab}!" => '',
995 ],
996 'selectors' => [
997 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-skewX: {{SIZE}}deg;',
998 ],
999 'frontend_available' => true,
1000 ]
1001 );
1002
1003 $this->add_responsive_control(
1004 "_transform_skewY_effect{$tab}",
1005 [
1006 'label' => esc_html__( 'Skew Y', 'elementor' ),
1007 'type' => Controls_Manager::SLIDER,
1008 'range' => [
1009 'px' => [
1010 'min' => -360,
1011 'max' => 360,
1012 ],
1013 ],
1014 'condition' => [
1015 "_transform_skew_popover{$tab}!" => '',
1016 ],
1017 'selectors' => [
1018 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-skewY: {{SIZE}}deg;',
1019 ],
1020 'frontend_available' => true,
1021 ]
1022 );
1023
1024 $this->end_popover();
1025
1026 $this->add_control(
1027 "_transform_flipX_effect{$tab}",
1028 [
1029 'label' => esc_html__( 'Flip Horizontal', 'elementor' ),
1030 'type' => Controls_Manager::CHOOSE,
1031 'options' => [
1032 'transform' => [
1033 'title' => esc_html__( 'Flip Horizontal', 'elementor' ),
1034 'icon' => 'eicon-flip eicon-tilted',
1035 ],
1036 ],
1037 'prefix_class' => $transform_prefix_class,
1038 'selectors' => [
1039 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-flipX: -1',
1040 ],
1041 'frontend_available' => true,
1042 ]
1043 );
1044
1045 $this->add_control(
1046 "_transform_flipY_effect{$tab}",
1047 [
1048 'label' => esc_html__( 'Flip Vertical', 'elementor' ),
1049 'type' => Controls_Manager::CHOOSE,
1050 'options' => [
1051 'transform' => [
1052 'title' => esc_html__( 'Flip Vertical', 'elementor' ),
1053 'icon' => 'eicon-flip',
1054 ],
1055 ],
1056 'prefix_class' => $transform_prefix_class,
1057 'selectors' => [
1058 "{{WRAPPER}} > .elementor-widget-container{$state}" => '--e-transform-flipY: -1',
1059 ],
1060 'frontend_available' => true,
1061 ]
1062 );
1063
1064 if ( '_hover' === $tab ) {
1065 $this->add_control(
1066 '_transform_transition_hover',
1067 [
1068 'label' => esc_html__( 'Transition Duration (ms)', 'elementor' ),
1069 'type' => Controls_Manager::SLIDER,
1070 'range' => [
1071 'px' => [
1072 'min' => 100,
1073 'max' => 10000,
1074 ],
1075 ],
1076 'selectors' => [
1077 '{{WRAPPER}} > .elementor-widget-container' => '--e-transform-transition-duration: {{SIZE}}ms',
1078 ],
1079 ]
1080 );
1081 }
1082
1083 ${"transform_origin_conditions{$tab}"} = [
1084 [
1085 'name' => "_transform_scale_popover{$tab}",
1086 'operator' => '!=',
1087 'value' => '',
1088 ],
1089 [
1090 'name' => "_transform_rotate_popover{$tab}",
1091 'operator' => '!=',
1092 'value' => '',
1093 ],
1094 [
1095 'name' => "_transform_flipX_effect{$tab}",
1096 'operator' => '!=',
1097 'value' => '',
1098 ],
1099 [
1100 'name' => "_transform_flipY_effect{$tab}",
1101 'operator' => '!=',
1102 'value' => '',
1103 ],
1104 ];
1105
1106 $this->end_controls_tab();
1107 }
1108
1109 $this->end_controls_tabs();
1110
1111 $transform_origin_conditions = [
1112 'relation' => 'or',
1113 'terms' => array_merge( $transform_origin_conditions, $transform_origin_conditions_hover ),
1114 ];
1115
1116 // Will override motion effect transform-origin
1117 $this->add_responsive_control(
1118 'motion_fx_transform_x_anchor_point',
1119 [
1120 'label' => esc_html__( 'X Anchor Point', 'elementor' ),
1121 'type' => Controls_Manager::CHOOSE,
1122 'options' => [
1123 'left' => [
1124 'title' => esc_html__( 'Left', 'elementor' ),
1125 'icon' => 'eicon-h-align-left',
1126 ],
1127 'center' => [
1128 'title' => esc_html__( 'Center', 'elementor' ),
1129 'icon' => 'eicon-h-align-center',
1130 ],
1131 'right' => [
1132 'title' => esc_html__( 'Right', 'elementor' ),
1133 'icon' => 'eicon-h-align-right',
1134 ],
1135 ],
1136 'conditions' => $transform_origin_conditions,
1137 'separator' => 'before',
1138 'selectors' => [
1139 '{{WRAPPER}}' => '--e-transform-origin-x: {{VALUE}}',
1140 ],
1141 ]
1142 );
1143
1144 // Will override motion effect transform-origin
1145 $this->add_responsive_control(
1146 'motion_fx_transform_y_anchor_point',
1147 [
1148 'label' => esc_html__( 'Y Anchor Point', 'elementor' ),
1149 'type' => Controls_Manager::CHOOSE,
1150 'options' => [
1151 'top' => [
1152 'title' => esc_html__( 'Top', 'elementor' ),
1153 'icon' => 'eicon-v-align-top',
1154 ],
1155 'center' => [
1156 'title' => esc_html__( 'Center', 'elementor' ),
1157 'icon' => 'eicon-v-align-middle',
1158 ],
1159 'bottom' => [
1160 'title' => esc_html__( 'Bottom', 'elementor' ),
1161 'icon' => 'eicon-v-align-bottom',
1162 ],
1163 ],
1164 'conditions' => $transform_origin_conditions,
1165 'selectors' => [
1166 '{{WRAPPER}}' => '--e-transform-origin-y: {{VALUE}}',
1167 ],
1168 ]
1169 );
1170
1171 $this->end_controls_section();
1172 }
1173
1174 /**
1175 * Register the Background section.
1176 *
1177 * @return void
1178 */
1179 private function register_background_section() {
1180 $this->start_controls_section(
1181 '_section_background',
1182 [
1183 'label' => esc_html__( 'Background', 'elementor' ),
1184 'tab' => Controls_Manager::TAB_ADVANCED,
1185 ]
1186 );
1187
1188 $this->start_controls_tabs( '_tabs_background' );
1189
1190 $this->start_controls_tab(
1191 '_tab_background_normal',
1192 [
1193 'label' => esc_html__( 'Normal', 'elementor' ),
1194 ]
1195 );
1196
1197 $this->add_group_control(
1198 Group_Control_Background::get_type(),
1199 [
1200 'name' => '_background',
1201 'selector' => '{{WRAPPER}} > .elementor-widget-container',
1202 ]
1203 );
1204
1205 $this->end_controls_tab();
1206
1207 $this->start_controls_tab(
1208 '_tab_background_hover',
1209 [
1210 'label' => esc_html__( 'Hover', 'elementor' ),
1211 ]
1212 );
1213
1214 $this->add_group_control(
1215 Group_Control_Background::get_type(),
1216 [
1217 'name' => '_background_hover',
1218 'selector' => '{{WRAPPER}}:hover .elementor-widget-container',
1219 ]
1220 );
1221
1222 $this->add_control(
1223 '_background_hover_transition',
1224 [
1225 'label' => esc_html__( 'Transition Duration', 'elementor' ),
1226 'type' => Controls_Manager::SLIDER,
1227 'range' => [
1228 'px' => [
1229 'max' => 3,
1230 'step' => 0.1,
1231 ],
1232 ],
1233 'render_type' => 'ui',
1234 'separator' => 'before',
1235 'selectors' => [
1236 '{{WRAPPER}} > .elementor-widget-container' => 'transition: background {{SIZE}}s',
1237 ],
1238 ]
1239 );
1240
1241 $this->end_controls_tab();
1242
1243 $this->end_controls_tabs();
1244
1245 $this->end_controls_section();
1246 }
1247
1248 /**
1249 * Register the Border section.
1250 *
1251 * @return void
1252 */
1253 private function register_border_section() {
1254 $this->start_controls_section(
1255 '_section_border',
1256 [
1257 'label' => esc_html__( 'Border', 'elementor' ),
1258 'tab' => Controls_Manager::TAB_ADVANCED,
1259 ]
1260 );
1261
1262 $this->start_controls_tabs( '_tabs_border' );
1263
1264 $this->start_controls_tab(
1265 '_tab_border_normal',
1266 [
1267 'label' => esc_html__( 'Normal', 'elementor' ),
1268 ]
1269 );
1270
1271 $this->add_group_control(
1272 Group_Control_Border::get_type(),
1273 [
1274 'name' => '_border',
1275 'selector' => '{{WRAPPER}} > .elementor-widget-container',
1276 ]
1277 );
1278
1279 $this->add_responsive_control(
1280 '_border_radius',
1281 [
1282 'label' => esc_html__( 'Border Radius', 'elementor' ),
1283 'type' => Controls_Manager::DIMENSIONS,
1284 'size_units' => [ 'px', '%' ],
1285 'selectors' => [
1286 '{{WRAPPER}} > .elementor-widget-container' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1287 ],
1288 ]
1289 );
1290
1291 $this->add_group_control(
1292 Group_Control_Box_Shadow::get_type(),
1293 [
1294 'name' => '_box_shadow',
1295 'selector' => '{{WRAPPER}} > .elementor-widget-container',
1296 ]
1297 );
1298
1299 $this->end_controls_tab();
1300
1301 $this->start_controls_tab(
1302 '_tab_border_hover',
1303 [
1304 'label' => esc_html__( 'Hover', 'elementor' ),
1305 ]
1306 );
1307
1308 $this->add_group_control(
1309 Group_Control_Border::get_type(),
1310 [
1311 'name' => '_border_hover',
1312 'selector' => '{{WRAPPER}}:hover .elementor-widget-container',
1313 ]
1314 );
1315
1316 $this->add_responsive_control(
1317 '_border_radius_hover',
1318 [
1319 'label' => esc_html__( 'Border Radius', 'elementor' ),
1320 'type' => Controls_Manager::DIMENSIONS,
1321 'size_units' => [ 'px', '%' ],
1322 'selectors' => [
1323 '{{WRAPPER}}:hover > .elementor-widget-container' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1324 ],
1325 ]
1326 );
1327
1328 $this->add_group_control(
1329 Group_Control_Box_Shadow::get_type(),
1330 [
1331 'name' => '_box_shadow_hover',
1332 'selector' => '{{WRAPPER}}:hover .elementor-widget-container',
1333 ]
1334 );
1335
1336 $this->add_control(
1337 '_border_hover_transition',
1338 [
1339 'label' => esc_html__( 'Transition Duration', 'elementor' ),
1340 'type' => Controls_Manager::SLIDER,
1341 'separator' => 'before',
1342 'range' => [
1343 'px' => [
1344 'max' => 3,
1345 'step' => 0.1,
1346 ],
1347 ],
1348 'selectors' => [
1349 '{{WRAPPER}} .elementor-widget-container' => 'transition: background {{_background_hover_transition.SIZE}}s, border {{SIZE}}s, border-radius {{SIZE}}s, box-shadow {{SIZE}}s',
1350 ],
1351 ]
1352 );
1353
1354 $this->end_controls_tab();
1355
1356 $this->end_controls_tabs();
1357
1358 $this->end_controls_section();
1359 }
1360
1361
1362 /**
1363 * Register the Mask section.
1364 *
1365 * @return void
1366 */
1367 private function register_masking_section() {
1368 $this->start_controls_section(
1369 '_section_masking',
1370 [
1371 'label' => esc_html__( 'Mask', 'elementor' ),
1372 'tab' => Controls_Manager::TAB_ADVANCED,
1373 ]
1374 );
1375
1376 $this->add_control(
1377 '_mask_switch',
1378 [
1379 'label' => esc_html__( 'Mask', 'elementor' ),
1380 'type' => Controls_Manager::SWITCHER,
1381 'label_on' => esc_html__( 'On', 'elementor' ),
1382 'label_off' => esc_html__( 'Off', 'elementor' ),
1383 'default' => '',
1384 ]
1385 );
1386
1387 $this->add_control(
1388 '_mask_shape',
1389 [
1390 'label' => esc_html__( 'Shape', 'elementor' ),
1391 'type' => Controls_Manager::SELECT,
1392 'options' => $this->get_shapes(),
1393 'default' => 'circle',
1394 'selectors' => $this->get_mask_selectors( '-webkit-mask-image: url( ' . ELEMENTOR_ASSETS_URL . '/mask-shapes/{{VALUE}}.svg );' ),
1395 'condition' => [
1396 '_mask_switch!' => '',
1397 ],
1398 ]
1399 );
1400
1401 $this->add_control(
1402 '_mask_image',
1403 [
1404 'label' => esc_html__( 'Image', 'elementor' ),
1405 'type' => Controls_Manager::MEDIA,
1406 'media_type' => 'image',
1407 'should_include_svg_inline_option' => true,
1408 'library_type' => 'image/svg+xml',
1409 'dynamic' => [
1410 'active' => true,
1411 ],
1412 'selectors' => $this->get_mask_selectors( '-webkit-mask-image: url( {{URL}} );' ),
1413 'condition' => [
1414 '_mask_switch!' => '',
1415 '_mask_shape' => 'custom',
1416 ],
1417 ]
1418 );
1419
1420 $this->add_control(
1421 '_mask_notice',
1422 [
1423 'type' => Controls_Manager::HIDDEN,
1424 'raw' => esc_html__( 'Need More Shapes?', 'elementor' ) .
1425 '<br>' .
1426 sprintf(
1427 /* translators: 1: Link open tag, 2: Link close tag. */
1428 esc_html__( 'Explore additional Premium Shape packs and use them in your site. %1$sLearn More%2$s', 'elementor' ),
1429 '<a target="_blank" href="https://go.elementor.com/mask-control">',
1430 '</a>'
1431 ),
1432 'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
1433 'condition' => [
1434 '_mask_switch!' => '',
1435 ],
1436 ]
1437 );
1438
1439 $this->add_responsive_control(
1440 '_mask_size',
1441 [
1442 'label' => esc_html__( 'Size', 'elementor' ),
1443 'type' => Controls_Manager::SELECT,
1444 'options' => [
1445 'contain' => esc_html__( 'Fit', 'elementor' ),
1446 'cover' => esc_html__( 'Fill', 'elementor' ),
1447 'custom' => esc_html__( 'Custom', 'elementor' ),
1448 ],
1449 'default' => 'contain',
1450 'selectors' => $this->get_mask_selectors( '-webkit-mask-size: {{VALUE}};' ),
1451 'condition' => [
1452 '_mask_switch!' => '',
1453 ],
1454 ]
1455 );
1456
1457 $this->add_responsive_control(
1458 '_mask_size_scale',
1459 [
1460 'label' => esc_html__( 'Scale', 'elementor' ),
1461 'type' => Controls_Manager::SLIDER,
1462 'size_units' => [ 'px', 'em', '%', 'vw' ],
1463 'range' => [
1464 'px' => [
1465 'min' => 0,
1466 'max' => 500,
1467 ],
1468 'em' => [
1469 'min' => 0,
1470 'max' => 100,
1471 ],
1472 '%' => [
1473 'min' => 0,
1474 'max' => 200,
1475 ],
1476 'vw' => [
1477 'min' => 0,
1478 'max' => 100,
1479 ],
1480 ],
1481 'default' => [
1482 'unit' => '%',
1483 'size' => 100,
1484 ],
1485 'selectors' => $this->get_mask_selectors( '-webkit-mask-size: {{SIZE}}{{UNIT}};' ),
1486 'condition' => [
1487 '_mask_switch!' => '',
1488 '_mask_size' => 'custom',
1489 ],
1490 ]
1491 );
1492
1493 $this->add_responsive_control(
1494 '_mask_position',
1495 [
1496 'label' => esc_html__( 'Position', 'elementor' ),
1497 'type' => Controls_Manager::SELECT,
1498 'options' => [
1499 'center center' => esc_html__( 'Center Center', 'elementor' ),
1500 'center left' => esc_html__( 'Center Left', 'elementor' ),
1501 'center right' => esc_html__( 'Center Right', 'elementor' ),
1502 'top center' => esc_html__( 'Top Center', 'elementor' ),
1503 'top left' => esc_html__( 'Top Left', 'elementor' ),
1504 'top right' => esc_html__( 'Top Right', 'elementor' ),
1505 'bottom center' => esc_html__( 'Bottom Center', 'elementor' ),
1506 'bottom left' => esc_html__( 'Bottom Left', 'elementor' ),
1507 'bottom right' => esc_html__( 'Bottom Right', 'elementor' ),
1508 'custom' => esc_html__( 'Custom', 'elementor' ),
1509 ],
1510 'default' => 'center center',
1511 'selectors' => $this->get_mask_selectors( '-webkit-mask-position: {{VALUE}};' ),
1512 'condition' => [
1513 '_mask_switch!' => '',
1514 ],
1515 ]
1516 );
1517
1518 $this->add_responsive_control(
1519 '_mask_position_x',
1520 [
1521 'label' => esc_html__( 'X Position', 'elementor' ),
1522 'type' => Controls_Manager::SLIDER,
1523 'size_units' => [ 'px', 'em', '%', 'vw' ],
1524 'range' => [
1525 'px' => [
1526 'min' => -500,
1527 'max' => 500,
1528 ],
1529 'em' => [
1530 'min' => -100,
1531 'max' => 100,
1532 ],
1533 '%' => [
1534 'min' => -100,
1535 'max' => 100,
1536 ],
1537 'vw' => [
1538 'min' => -100,
1539 'max' => 100,
1540 ],
1541 ],
1542 'default' => [
1543 'unit' => '%',
1544 'size' => 0,
1545 ],
1546 'selectors' => $this->get_mask_selectors( '-webkit-mask-position-x: {{SIZE}}{{UNIT}};' ),
1547 'condition' => [
1548 '_mask_switch!' => '',
1549 '_mask_position' => 'custom',
1550 ],
1551 ]
1552 );
1553
1554 $this->add_responsive_control(
1555 '_mask_position_y',
1556 [
1557 'label' => esc_html__( 'Y Position', 'elementor' ),
1558 'type' => Controls_Manager::SLIDER,
1559 'size_units' => [ 'px', 'em', '%', 'vw' ],
1560 'range' => [
1561 'px' => [
1562 'min' => -500,
1563 'max' => 500,
1564 ],
1565 'em' => [
1566 'min' => -100,
1567 'max' => 100,
1568 ],
1569 '%' => [
1570 'min' => -100,
1571 'max' => 100,
1572 ],
1573 'vw' => [
1574 'min' => -100,
1575 'max' => 100,
1576 ],
1577 ],
1578 'default' => [
1579 'unit' => '%',
1580 'size' => 0,
1581 ],
1582 'selectors' => $this->get_mask_selectors( '-webkit-mask-position-y: {{SIZE}}{{UNIT}};' ),
1583 'condition' => [
1584 '_mask_switch!' => '',
1585 '_mask_position' => 'custom',
1586 ],
1587 ]
1588 );
1589
1590 $this->add_responsive_control(
1591 '_mask_repeat',
1592 [
1593 'label' => esc_html__( 'Repeat', 'elementor' ),
1594 'type' => Controls_Manager::SELECT,
1595 'options' => [
1596 'no-repeat' => esc_html__( 'No-Repeat', 'elementor' ),
1597 'repeat' => esc_html__( 'Repeat', 'elementor' ),
1598 'repeat-x' => esc_html__( 'Repeat-X', 'elementor' ),
1599 'repeat-Y' => esc_html__( 'Repeat-Y', 'elementor' ),
1600 'round' => esc_html__( 'Round', 'elementor' ),
1601 'space' => esc_html__( 'Space', 'elementor' ),
1602 ],
1603 'default' => 'no-repeat',
1604 'selectors' => $this->get_mask_selectors( '-webkit-mask-repeat: {{VALUE}};' ),
1605 'condition' => [
1606 '_mask_switch!' => '',
1607 '_mask_size!' => 'cover',
1608 ],
1609 ]
1610 );
1611
1612 $this->end_controls_section();
1613 }
1614
1615
1616 /**
1617 * Register the Responsive section.
1618 *
1619 * @return void
1620 */
1621 private function register_responsive_section() {
1622 $this->start_controls_section(
1623 '_section_responsive',
1624 [
1625 'label' => esc_html__( 'Responsive', 'elementor' ),
1626 'tab' => Controls_Manager::TAB_ADVANCED,
1627 ]
1628 );
1629
1630 $this->add_control(
1631 'responsive_description',
1632 [
1633 'raw' => esc_html__( 'Responsive visibility will take effect only on preview or live page, and not while editing in Elementor.', 'elementor' ),
1634 'type' => Controls_Manager::RAW_HTML,
1635 'content_classes' => 'elementor-descriptor',
1636 ]
1637 );
1638
1639 $this->add_hidden_device_controls();
1640
1641 $this->end_controls_section();
1642 }
1643
1644 /**
1645 * Register common widget controls.
1646 *
1647 * Adds different input fields to allow the user to change and customize the widget settings.
1648 *
1649 * @since 3.1.0
1650 * @access protected
1651 */
1652 protected function register_controls() {
1653 $this->register_layout_section();
1654
1655 $this->register_effects_section();
1656
1657 $this->register_transform_section();
1658
1659 $this->register_background_section();
1660
1661 $this->register_border_section();
1662
1663 $this->register_masking_section();
1664
1665 $this->register_responsive_section();
1666
1667 Plugin::$instance->controls_manager->add_custom_attributes_controls( $this );
1668
1669 Plugin::$instance->controls_manager->add_custom_css_controls( $this );
1670 }
1671 }
1672