balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

column.php (27518B)


      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 column element.
     12  *
     13  * Elementor column handler class is responsible for initializing the column
     14  * element.
     15  *
     16  * @since 1.0.0
     17  */
     18 class Element_Column extends Element_Base {
     19 
     20 	/**
     21 	 * Get column name.
     22 	 *
     23 	 * Retrieve the column name.
     24 	 *
     25 	 * @since 1.0.0
     26 	 * @access public
     27 	 *
     28 	 * @return string Column name.
     29 	 */
     30 	public function get_name() {
     31 		return 'column';
     32 	}
     33 
     34 	/**
     35 	 * Get element type.
     36 	 *
     37 	 * Retrieve the element type, in this case `column`.
     38 	 *
     39 	 * @since 2.1.0
     40 	 * @access public
     41 	 * @static
     42 	 *
     43 	 * @return string The type.
     44 	 */
     45 	public static function get_type() {
     46 		return 'column';
     47 	}
     48 
     49 	/**
     50 	 * Get column title.
     51 	 *
     52 	 * Retrieve the column title.
     53 	 *
     54 	 * @since 1.0.0
     55 	 * @access public
     56 	 *
     57 	 * @return string Column title.
     58 	 */
     59 	public function get_title() {
     60 		return esc_html__( 'Column', 'elementor' );
     61 	}
     62 
     63 	/**
     64 	 * Get column icon.
     65 	 *
     66 	 * Retrieve the column icon.
     67 	 *
     68 	 * @since 1.0.0
     69 	 * @access public
     70 	 *
     71 	 * @return string Column icon.
     72 	 */
     73 	public function get_icon() {
     74 		return 'eicon-column';
     75 	}
     76 
     77 	/**
     78 	 * Get initial config.
     79 	 *
     80 	 * Retrieve the current section initial configuration.
     81 	 *
     82 	 * Adds more configuration on top of the controls list, the tabs assigned to
     83 	 * the control, element name, type, icon and more. This method also adds
     84 	 * section presets.
     85 	 *
     86 	 * @since 2.9.0
     87 	 * @access protected
     88 	 *
     89 	 * @return array The initial config.
     90 	 */
     91 	protected function get_initial_config() {
     92 		$config = parent::get_initial_config();
     93 
     94 		$config['controls'] = $this->get_controls();
     95 		$config['tabs_controls'] = $this->get_tabs_controls();
     96 
     97 		return $config;
     98 	}
     99 
    100 	/**
    101 	 * Register column controls.
    102 	 *
    103 	 * Used to add new controls to the column element.
    104 	 *
    105 	 * @since 3.1.0
    106 	 * @access protected
    107 	 */
    108 	protected function register_controls() {
    109 		// Section Layout.
    110 		$this->start_controls_section(
    111 			'layout',
    112 			[
    113 				'label' => esc_html__( 'Layout', 'elementor' ),
    114 				'tab' => Controls_Manager::TAB_LAYOUT,
    115 			]
    116 		);
    117 
    118 		// Element Name for the Navigator
    119 		$this->add_control(
    120 			'_title',
    121 			[
    122 				'label' => esc_html__( 'Title', 'elementor' ),
    123 				'type' => Controls_Manager::HIDDEN,
    124 				'render_type' => 'none',
    125 			]
    126 		);
    127 
    128 		$active_breakpoint_keys = array_reverse( array_keys( Plugin::$instance->breakpoints->get_active_breakpoints() ) );
    129 		$inline_size_device_args = [
    130 			Breakpoints_Manager::BREAKPOINT_KEY_MOBILE => [ 'placeholder' => 100 ],
    131 		];
    132 
    133 		foreach ( $active_breakpoint_keys as $breakpoint_key ) {
    134 			if ( ! isset( $inline_size_device_args[ $breakpoint_key ] ) ) {
    135 				$inline_size_device_args[ $breakpoint_key ] = [];
    136 			}
    137 
    138 			$inline_size_device_args[ $breakpoint_key ] = array_merge_recursive(
    139 				$inline_size_device_args[ $breakpoint_key ],
    140 				[
    141 					'max' => 100,
    142 					'required' => false,
    143 				]
    144 			);
    145 		}
    146 
    147 		if ( in_array( Breakpoints_Manager::BREAKPOINT_KEY_MOBILE_EXTRA, $active_breakpoint_keys, true ) ) {
    148 			$min_affected_device_value = Breakpoints_Manager::BREAKPOINT_KEY_MOBILE_EXTRA;
    149 		} else {
    150 			$min_affected_device_value = Breakpoints_Manager::BREAKPOINT_KEY_TABLET;
    151 		}
    152 
    153 		$this->add_responsive_control(
    154 			'_inline_size',
    155 			[
    156 				'label' => esc_html__( 'Column Width', 'elementor' ) . ' (%)',
    157 				'type' => Controls_Manager::NUMBER,
    158 				'min' => 2,
    159 				'max' => 98,
    160 				'required' => true,
    161 				'device_args' => $inline_size_device_args,
    162 				'min_affected_device' => [
    163 					Breakpoints_Manager::BREAKPOINT_KEY_DESKTOP => $min_affected_device_value,
    164 					Breakpoints_Manager::BREAKPOINT_KEY_LAPTOP => $min_affected_device_value,
    165 					Breakpoints_Manager::BREAKPOINT_KEY_TABLET_EXTRA => $min_affected_device_value,
    166 					Breakpoints_Manager::BREAKPOINT_KEY_TABLET => $min_affected_device_value,
    167 					Breakpoints_Manager::BREAKPOINT_KEY_MOBILE_EXTRA => $min_affected_device_value,
    168 				],
    169 				'selectors' => [
    170 					'{{WRAPPER}}' => 'width: {{VALUE}}%',
    171 				],
    172 			]
    173 		);
    174 
    175 		$is_dome_optimization_active = Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' );
    176 		$main_selector_element = $is_dome_optimization_active ? 'widget' : 'column';
    177 		$widget_wrap_child = $is_dome_optimization_active ? '' : ' > .elementor-widget-wrap';
    178 		$column_wrap_child = $is_dome_optimization_active ? '' : ' > .elementor-column-wrap';
    179 
    180 		$this->add_responsive_control(
    181 			'content_position',
    182 			[
    183 				'label' => esc_html__( 'Vertical Align', 'elementor' ),
    184 				'type' => Controls_Manager::SELECT,
    185 				'default' => '',
    186 				'options' => [
    187 					'' => esc_html__( 'Default', 'elementor' ),
    188 					'top' => esc_html__( 'Top', 'elementor' ),
    189 					'center' => esc_html__( 'Middle', 'elementor' ),
    190 					'bottom' => esc_html__( 'Bottom', 'elementor' ),
    191 					'space-between' => esc_html__( 'Space Between', 'elementor' ),
    192 					'space-around' => esc_html__( 'Space Around', 'elementor' ),
    193 					'space-evenly' => esc_html__( 'Space Evenly', 'elementor' ),
    194 				],
    195 				'selectors_dictionary' => [
    196 					'top' => 'flex-start',
    197 					'bottom' => 'flex-end',
    198 				],
    199 				'selectors' => [
    200 					// TODO: The following line is for BC since 2.7.0
    201 					'.elementor-bc-flex-widget {{WRAPPER}}.elementor-column .elementor-' . $main_selector_element . '-wrap' => 'align-items: {{VALUE}}',
    202 					// This specificity is intended to make sure column css overwrites section css on vertical alignment (content_position)
    203 					'{{WRAPPER}}.elementor-column.elementor-element[data-element_type="column"] > .elementor-' . $main_selector_element . '-wrap.elementor-element-populated' . $widget_wrap_child => 'align-content: {{VALUE}}; align-items: {{VALUE}};',
    204 				],
    205 			]
    206 		);
    207 
    208 		$this->add_responsive_control(
    209 			'align',
    210 			[
    211 				'label' => esc_html__( 'Horizontal Align', 'elementor' ),
    212 				'type' => Controls_Manager::SELECT,
    213 				'default' => '',
    214 				'options' => [
    215 					'' => esc_html__( 'Default', 'elementor' ),
    216 					'flex-start' => esc_html__( 'Start', 'elementor' ),
    217 					'center' => esc_html__( 'Center', 'elementor' ),
    218 					'flex-end' => esc_html__( 'End', 'elementor' ),
    219 					'space-between' => esc_html__( 'Space Between', 'elementor' ),
    220 					'space-around' => esc_html__( 'Space Around', 'elementor' ),
    221 					'space-evenly' => esc_html__( 'Space Evenly', 'elementor' ),
    222 				],
    223 				'selectors' => [
    224 					'{{WRAPPER}}.elementor-column' . $column_wrap_child . ' > .elementor-widget-wrap' => 'justify-content: {{VALUE}}',
    225 				],
    226 			]
    227 		);
    228 
    229 		$space_between_widgets_selector = $is_dome_optimization_active ? '' : '> .elementor-column-wrap ';
    230 
    231 		$this->add_responsive_control(
    232 			'space_between_widgets',
    233 			[
    234 				'label' => esc_html__( 'Widgets Space', 'elementor' ) . ' (px)',
    235 				'type' => Controls_Manager::NUMBER,
    236 				'placeholder' => 20,
    237 				'selectors' => [
    238 					'{{WRAPPER}} ' . $space_between_widgets_selector . '> .elementor-widget-wrap > .elementor-widget:not(.elementor-widget__width-auto):not(.elementor-widget__width-initial):not(:last-child):not(.elementor-absolute)' => 'margin-bottom: {{VALUE}}px', //Need the full path for exclude the inner section
    239 				],
    240 			]
    241 		);
    242 
    243 		$possible_tags = [
    244 			'div',
    245 			'header',
    246 			'footer',
    247 			'main',
    248 			'article',
    249 			'section',
    250 			'aside',
    251 			'nav',
    252 		];
    253 
    254 		$options = [
    255 			'' => esc_html__( 'Default', 'elementor' ),
    256 		] + array_combine( $possible_tags, $possible_tags );
    257 
    258 		$this->add_control(
    259 			'html_tag',
    260 			[
    261 				'label' => esc_html__( 'HTML Tag', 'elementor' ),
    262 				'type' => Controls_Manager::SELECT,
    263 				'options' => $options,
    264 				'render_type' => 'none',
    265 			]
    266 		);
    267 
    268 		$this->end_controls_section();
    269 
    270 		$this->start_controls_section(
    271 			'section_style',
    272 			[
    273 				'label' => esc_html__( 'Background', 'elementor' ),
    274 				'tab' => Controls_Manager::TAB_STYLE,
    275 			]
    276 		);
    277 
    278 		$this->start_controls_tabs( 'tabs_background' );
    279 
    280 		$this->start_controls_tab(
    281 			'tab_background_normal',
    282 			[
    283 				'label' => esc_html__( 'Normal', 'elementor' ),
    284 			]
    285 		);
    286 
    287 		$this->add_group_control(
    288 			Group_Control_Background::get_type(),
    289 			[
    290 				'name' => 'background',
    291 				'types' => [ 'classic', 'gradient', 'slideshow' ],
    292 				'selector' => '{{WRAPPER}}:not(.elementor-motion-effects-element-type-background) > .elementor-' . $main_selector_element . '-wrap, {{WRAPPER}} > .elementor-' . $main_selector_element . '-wrap > .elementor-motion-effects-container > .elementor-motion-effects-layer',
    293 				'fields_options' => [
    294 					'background' => [
    295 						'frontend_available' => true,
    296 					],
    297 				],
    298 			]
    299 		);
    300 
    301 		$this->end_controls_tab();
    302 
    303 		$this->start_controls_tab(
    304 			'tab_background_hover',
    305 			[
    306 				'label' => esc_html__( 'Hover', 'elementor' ),
    307 			]
    308 		);
    309 
    310 		$this->add_group_control(
    311 			Group_Control_Background::get_type(),
    312 			[
    313 				'name' => 'background_hover',
    314 				'selector' => '{{WRAPPER}}:hover > .elementor-element-populated',
    315 			]
    316 		);
    317 
    318 		$this->add_control(
    319 			'background_hover_transition',
    320 			[
    321 				'label' => esc_html__( 'Transition Duration', 'elementor' ),
    322 				'type' => Controls_Manager::SLIDER,
    323 				'default' => [
    324 					'size' => 0.3,
    325 				],
    326 				'range' => [
    327 					'px' => [
    328 						'max' => 3,
    329 						'step' => 0.1,
    330 					],
    331 				],
    332 				'render_type' => 'ui',
    333 				'separator' => 'before',
    334 			]
    335 		);
    336 
    337 		$this->end_controls_tab();
    338 
    339 		$this->end_controls_tabs();
    340 
    341 		$this->end_controls_section();
    342 
    343 		// Section Column Background Overlay.
    344 		$this->start_controls_section(
    345 			'section_background_overlay',
    346 			[
    347 				'label' => esc_html__( 'Background Overlay', 'elementor' ),
    348 				'tab' => Controls_Manager::TAB_STYLE,
    349 				'condition' => [
    350 					'background_background' => [ 'classic', 'gradient' ],
    351 				],
    352 			]
    353 		);
    354 
    355 		$this->start_controls_tabs( 'tabs_background_overlay' );
    356 
    357 		$this->start_controls_tab(
    358 			'tab_background_overlay_normal',
    359 			[
    360 				'label' => esc_html__( 'Normal', 'elementor' ),
    361 			]
    362 		);
    363 
    364 		$this->add_group_control(
    365 			Group_Control_Background::get_type(),
    366 			[
    367 				'name' => 'background_overlay',
    368 				'selector' => '{{WRAPPER}} > .elementor-element-populated >  .elementor-background-overlay',
    369 			]
    370 		);
    371 
    372 		$this->add_control(
    373 			'background_overlay_opacity',
    374 			[
    375 				'label' => esc_html__( 'Opacity', 'elementor' ),
    376 				'type' => Controls_Manager::SLIDER,
    377 				'default' => [
    378 					'size' => .5,
    379 				],
    380 				'range' => [
    381 					'px' => [
    382 						'max' => 1,
    383 						'step' => 0.01,
    384 					],
    385 				],
    386 				'selectors' => [
    387 					'{{WRAPPER}} > .elementor-element-populated >  .elementor-background-overlay' => 'opacity: {{SIZE}};',
    388 				],
    389 				'condition' => [
    390 					'background_overlay_background' => [ 'classic', 'gradient' ],
    391 				],
    392 			]
    393 		);
    394 
    395 		$this->add_group_control(
    396 			Group_Control_Css_Filter::get_type(),
    397 			[
    398 				'name' => 'css_filters',
    399 				'selector' => '{{WRAPPER}} > .elementor-element-populated >  .elementor-background-overlay',
    400 			]
    401 		);
    402 
    403 		$this->add_control(
    404 			'overlay_blend_mode',
    405 			[
    406 				'label' => esc_html__( 'Blend Mode', 'elementor' ),
    407 				'type' => Controls_Manager::SELECT,
    408 				'options' => [
    409 					'' => esc_html__( 'Normal', 'elementor' ),
    410 					'multiply' => esc_html__( 'Multiply', 'elementor' ),
    411 					'screen' => esc_html__( 'Screen', 'elementor' ),
    412 					'overlay' => esc_html__( 'Overlay', 'elementor' ),
    413 					'darken' => esc_html__( 'Darken', 'elementor' ),
    414 					'lighten' => esc_html__( 'Lighten', 'elementor' ),
    415 					'color-dodge' => esc_html__( 'Color Dodge', 'elementor' ),
    416 					'saturation' => esc_html__( 'Saturation', 'elementor' ),
    417 					'color' => esc_html__( 'Color', 'elementor' ),
    418 					'luminosity' => esc_html__( 'Luminosity', 'elementor' ),
    419 				],
    420 				'selectors' => [
    421 					'{{WRAPPER}} > .elementor-element-populated > .elementor-background-overlay' => 'mix-blend-mode: {{VALUE}}',
    422 				],
    423 			]
    424 		);
    425 
    426 		$this->end_controls_tab();
    427 
    428 		$this->start_controls_tab(
    429 			'tab_background_overlay_hover',
    430 			[
    431 				'label' => esc_html__( 'Hover', 'elementor' ),
    432 			]
    433 		);
    434 
    435 		$this->add_group_control(
    436 			Group_Control_Background::get_type(),
    437 			[
    438 				'name' => 'background_overlay_hover',
    439 				'selector' => '{{WRAPPER}}:hover > .elementor-element-populated >  .elementor-background-overlay',
    440 			]
    441 		);
    442 
    443 		$this->add_control(
    444 			'background_overlay_hover_opacity',
    445 			[
    446 				'label' => esc_html__( 'Opacity', 'elementor' ),
    447 				'type' => Controls_Manager::SLIDER,
    448 				'default' => [
    449 					'size' => .5,
    450 				],
    451 				'range' => [
    452 					'px' => [
    453 						'max' => 1,
    454 						'step' => 0.01,
    455 					],
    456 				],
    457 				'selectors' => [
    458 					'{{WRAPPER}}:hover > .elementor-element-populated >  .elementor-background-overlay' => 'opacity: {{SIZE}};',
    459 				],
    460 				'condition' => [
    461 					'background_overlay_hover_background' => [ 'classic', 'gradient' ],
    462 				],
    463 			]
    464 		);
    465 
    466 		$this->add_group_control(
    467 			Group_Control_Css_Filter::get_type(),
    468 			[
    469 				'name' => 'css_filters_hover',
    470 				'selector' => '{{WRAPPER}}:hover > .elementor-element-populated >  .elementor-background-overlay',
    471 			]
    472 		);
    473 
    474 		$this->add_control(
    475 			'background_overlay_hover_transition',
    476 			[
    477 				'label' => esc_html__( 'Transition Duration', 'elementor' ),
    478 				'type' => Controls_Manager::SLIDER,
    479 				'default' => [
    480 					'size' => 0.3,
    481 				],
    482 				'range' => [
    483 					'px' => [
    484 						'max' => 3,
    485 						'step' => 0.1,
    486 					],
    487 				],
    488 				'render_type' => 'ui',
    489 				'separator' => 'before',
    490 			]
    491 		);
    492 
    493 		$this->end_controls_tab();
    494 
    495 		$this->end_controls_tabs();
    496 
    497 		$this->end_controls_section();
    498 
    499 		$this->start_controls_section(
    500 			'section_border',
    501 			[
    502 				'label' => esc_html__( 'Border', 'elementor' ),
    503 				'tab' => Controls_Manager::TAB_STYLE,
    504 			]
    505 		);
    506 
    507 		$this->start_controls_tabs( 'tabs_border' );
    508 
    509 		$this->start_controls_tab(
    510 			'tab_border_normal',
    511 			[
    512 				'label' => esc_html__( 'Normal', 'elementor' ),
    513 			]
    514 		);
    515 
    516 		$this->add_group_control(
    517 			Group_Control_Border::get_type(),
    518 			[
    519 				'name' => 'border',
    520 				'selector' => '{{WRAPPER}} > .elementor-element-populated',
    521 			]
    522 		);
    523 
    524 		$this->add_responsive_control(
    525 			'border_radius',
    526 			[
    527 				'label' => esc_html__( 'Border Radius', 'elementor' ),
    528 				'type' => Controls_Manager::DIMENSIONS,
    529 				'size_units' => [ 'px', '%' ],
    530 				'selectors' => [
    531 					'{{WRAPPER}} > .elementor-element-populated, {{WRAPPER}} > .elementor-element-populated > .elementor-background-overlay, {{WRAPPER}} > .elementor-background-slideshow' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
    532 				],
    533 			]
    534 		);
    535 
    536 		$this->add_group_control(
    537 			Group_Control_Box_Shadow::get_type(),
    538 			[
    539 				'name' => 'box_shadow',
    540 				'selector' => '{{WRAPPER}} > .elementor-element-populated',
    541 			]
    542 		);
    543 
    544 		$this->end_controls_tab();
    545 
    546 		$this->start_controls_tab(
    547 			'tab_border_hover',
    548 			[
    549 				'label' => esc_html__( 'Hover', 'elementor' ),
    550 			]
    551 		);
    552 
    553 		$this->add_group_control(
    554 			Group_Control_Border::get_type(),
    555 			[
    556 				'name' => 'border_hover',
    557 				'selector' => '{{WRAPPER}}:hover > .elementor-element-populated',
    558 			]
    559 		);
    560 
    561 		$this->add_responsive_control(
    562 			'border_radius_hover',
    563 			[
    564 				'label' => esc_html__( 'Border Radius', 'elementor' ),
    565 				'type' => Controls_Manager::DIMENSIONS,
    566 				'size_units' => [ 'px', '%' ],
    567 				'selectors' => [
    568 					'{{WRAPPER}}:hover > .elementor-element-populated, {{WRAPPER}}:hover > .elementor-element-populated > .elementor-background-overlay' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
    569 				],
    570 			]
    571 		);
    572 
    573 		$this->add_group_control(
    574 			Group_Control_Box_Shadow::get_type(),
    575 			[
    576 				'name' => 'box_shadow_hover',
    577 				'selector' => '{{WRAPPER}}:hover > .elementor-element-populated',
    578 			]
    579 		);
    580 
    581 		$this->add_control(
    582 			'border_hover_transition',
    583 			[
    584 				'label' => esc_html__( 'Transition Duration', 'elementor' ),
    585 				'type' => Controls_Manager::SLIDER,
    586 				'separator' => 'before',
    587 				'default' => [
    588 					'size' => 0.3,
    589 				],
    590 				'range' => [
    591 					'px' => [
    592 						'max' => 3,
    593 						'step' => 0.1,
    594 					],
    595 				],
    596 				'conditions' => [
    597 					'relation' => 'or',
    598 					'terms' => [
    599 						[
    600 							'name' => 'background_background',
    601 							'operator' => '!==',
    602 							'value' => '',
    603 						],
    604 						[
    605 							'name' => 'border_border',
    606 							'operator' => '!==',
    607 							'value' => '',
    608 						],
    609 					],
    610 				],
    611 				'selectors' => [
    612 					'{{WRAPPER}} > .elementor-element-populated' => 'transition: background {{background_hover_transition.SIZE}}s, border {{SIZE}}s, border-radius {{SIZE}}s, box-shadow {{SIZE}}s',
    613 					'{{WRAPPER}} > .elementor-element-populated > .elementor-background-overlay' => 'transition: background {{background_overlay_hover_transition.SIZE}}s, border-radius {{SIZE}}s, opacity {{background_overlay_hover_transition.SIZE}}s',
    614 				],
    615 			]
    616 		);
    617 
    618 		$this->end_controls_tab();
    619 
    620 		$this->end_controls_tabs();
    621 
    622 		$this->end_controls_section();
    623 
    624 		// Section Typography.
    625 		$this->start_controls_section(
    626 			'section_typo',
    627 			[
    628 				'label' => esc_html__( 'Typography', 'elementor' ),
    629 				'type' => Controls_Manager::SECTION,
    630 				'tab' => Controls_Manager::TAB_STYLE,
    631 			]
    632 		);
    633 
    634 		$this->add_control(
    635 			'heading_color',
    636 			[
    637 				'label' => esc_html__( 'Heading Color', 'elementor' ),
    638 				'type' => Controls_Manager::COLOR,
    639 				'default' => '',
    640 				'selectors' => [
    641 					'{{WRAPPER}} .elementor-element-populated .elementor-heading-title' => 'color: {{VALUE}};',
    642 				],
    643 				'separator' => 'none',
    644 			]
    645 		);
    646 
    647 		$this->add_control(
    648 			'color_text',
    649 			[
    650 				'label' => esc_html__( 'Text Color', 'elementor' ),
    651 				'type' => Controls_Manager::COLOR,
    652 				'default' => '',
    653 				'selectors' => [
    654 					'{{WRAPPER}} > .elementor-element-populated' => 'color: {{VALUE}};',
    655 				],
    656 			]
    657 		);
    658 
    659 		$this->add_control(
    660 			'color_link',
    661 			[
    662 				'label' => esc_html__( 'Link Color', 'elementor' ),
    663 				'type' => Controls_Manager::COLOR,
    664 				'default' => '',
    665 				'selectors' => [
    666 					'{{WRAPPER}} .elementor-element-populated a' => 'color: {{VALUE}};',
    667 				],
    668 			]
    669 		);
    670 
    671 		$this->add_control(
    672 			'color_link_hover',
    673 			[
    674 				'label' => esc_html__( 'Link Hover Color', 'elementor' ),
    675 				'type' => Controls_Manager::COLOR,
    676 				'default' => '',
    677 				'selectors' => [
    678 					'{{WRAPPER}} .elementor-element-populated a:hover' => 'color: {{VALUE}};',
    679 				],
    680 			]
    681 		);
    682 
    683 		$this->add_control(
    684 			'text_align',
    685 			[
    686 				'label' => esc_html__( 'Text Align', 'elementor' ),
    687 				'type' => Controls_Manager::CHOOSE,
    688 				'options' => [
    689 					'left' => [
    690 						'title' => esc_html__( 'Left', 'elementor' ),
    691 						'icon' => 'eicon-text-align-left',
    692 					],
    693 					'center' => [
    694 						'title' => esc_html__( 'Center', 'elementor' ),
    695 						'icon' => 'eicon-text-align-center',
    696 					],
    697 					'right' => [
    698 						'title' => esc_html__( 'Right', 'elementor' ),
    699 						'icon' => 'eicon-text-align-right',
    700 					],
    701 					'justify' => [
    702 						'title' => __( 'Justified', 'elementor' ),
    703 						'icon' => 'eicon-text-align-justify',
    704 					],
    705 				],
    706 				'selectors' => [
    707 					'{{WRAPPER}} > .elementor-element-populated' => 'text-align: {{VALUE}};',
    708 				],
    709 			]
    710 		);
    711 
    712 		$this->end_controls_section();
    713 
    714 		// Section Advanced.
    715 		$this->start_controls_section(
    716 			'section_advanced',
    717 			[
    718 				'label' => esc_html__( 'Advanced', 'elementor' ),
    719 				'type' => Controls_Manager::SECTION,
    720 				'tab' => Controls_Manager::TAB_ADVANCED,
    721 			]
    722 		);
    723 
    724 		$this->add_responsive_control(
    725 			'margin',
    726 			[
    727 				'label' => esc_html__( 'Margin', 'elementor' ),
    728 				'type' => Controls_Manager::DIMENSIONS,
    729 				'size_units' => [ 'px', 'em', '%', 'rem' ],
    730 				'selectors' => [
    731 					'{{WRAPPER}} > .elementor-element-populated' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
    732 				],
    733 			]
    734 		);
    735 
    736 		$this->add_responsive_control(
    737 			'padding',
    738 			[
    739 				'label' => esc_html__( 'Padding', 'elementor' ),
    740 				'type' => Controls_Manager::DIMENSIONS,
    741 				'size_units' => [ 'px', 'em', '%', 'rem' ],
    742 				'selectors' => [
    743 					'{{WRAPPER}} > .elementor-element-populated' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
    744 				],
    745 			]
    746 		);
    747 
    748 		$this->add_responsive_control(
    749 			'z_index',
    750 			[
    751 				'label' => esc_html__( 'Z-Index', 'elementor' ),
    752 				'type' => Controls_Manager::NUMBER,
    753 				'min' => 0,
    754 				'selectors' => [
    755 					'{{WRAPPER}}' => 'z-index: {{VALUE}};',
    756 				],
    757 			]
    758 		);
    759 
    760 		$this->add_control(
    761 			'_element_id',
    762 			[
    763 				'label' => esc_html__( 'CSS ID', 'elementor' ),
    764 				'type' => Controls_Manager::TEXT,
    765 				'default' => '',
    766 				'dynamic' => [
    767 					'active' => true,
    768 				],
    769 				'title' => esc_html__( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'elementor' ),
    770 				'style_transfer' => false,
    771 				'classes' => 'elementor-control-direction-ltr',
    772 			]
    773 		);
    774 
    775 		$this->add_control(
    776 			'css_classes',
    777 			[
    778 				'label' => esc_html__( 'CSS Classes', 'elementor' ),
    779 				'type' => Controls_Manager::TEXT,
    780 				'default' => '',
    781 				'dynamic' => [
    782 					'active' => true,
    783 				],
    784 				'prefix_class' => '',
    785 				'title' => esc_html__( 'Add your custom class WITHOUT the dot. e.g: my-class', 'elementor' ),
    786 				'classes' => 'elementor-control-direction-ltr',
    787 			]
    788 		);
    789 
    790 		// TODO: Backward comparability for deprecated controls
    791 		$this->add_control(
    792 			'screen_sm',
    793 			[
    794 				'type' => Controls_Manager::HIDDEN,
    795 			]
    796 		);
    797 
    798 		$this->add_control(
    799 			'screen_sm_width',
    800 			[
    801 				'type' => Controls_Manager::HIDDEN,
    802 				'condition' => [
    803 					'screen_sm' => [ 'custom' ],
    804 				],
    805 				'prefix_class' => 'elementor-sm-',
    806 			]
    807 		);
    808 		// END Backward comparability
    809 
    810 		$this->end_controls_section();
    811 
    812 		$this->start_controls_section(
    813 			'section_effects',
    814 			[
    815 				'label' => esc_html__( 'Motion Effects', 'elementor' ),
    816 				'tab' => Controls_Manager::TAB_ADVANCED,
    817 			]
    818 		);
    819 
    820 		$this->add_responsive_control(
    821 			'animation',
    822 			[
    823 				'label' => esc_html__( 'Entrance Animation', 'elementor' ),
    824 				'type' => Controls_Manager::ANIMATION,
    825 				'frontend_available' => true,
    826 			]
    827 		);
    828 
    829 		$this->add_control(
    830 			'animation_duration',
    831 			[
    832 				'label' => esc_html__( 'Animation Duration', 'elementor' ),
    833 				'type' => Controls_Manager::SELECT,
    834 				'default' => '',
    835 				'options' => [
    836 					'slow' => esc_html__( 'Slow', 'elementor' ),
    837 					'' => esc_html__( 'Normal', 'elementor' ),
    838 					'fast' => esc_html__( 'Fast', 'elementor' ),
    839 				],
    840 				'prefix_class' => 'animated-',
    841 				'condition' => [
    842 					'animation!' => '',
    843 				],
    844 			]
    845 		);
    846 
    847 		$this->add_control(
    848 			'animation_delay',
    849 			[
    850 				'label' => esc_html__( 'Animation Delay', 'elementor' ) . ' (ms)',
    851 				'type' => Controls_Manager::NUMBER,
    852 				'default' => '',
    853 				'min' => 0,
    854 				'step' => 100,
    855 				'condition' => [
    856 					'animation!' => '',
    857 				],
    858 				'render_type' => 'none',
    859 				'frontend_available' => true,
    860 			]
    861 		);
    862 
    863 		$this->end_controls_section();
    864 
    865 		$this->start_controls_section(
    866 			'_section_responsive',
    867 			[
    868 				'label' => esc_html__( 'Responsive', 'elementor' ),
    869 				'tab' => Controls_Manager::TAB_ADVANCED,
    870 			]
    871 		);
    872 
    873 		$this->add_control(
    874 			'responsive_description',
    875 			[
    876 				'raw' => esc_html__( 'Responsive visibility will take effect only on preview or live page, and not while editing in Elementor.', 'elementor' ),
    877 				'type' => Controls_Manager::RAW_HTML,
    878 				'content_classes' => 'elementor-descriptor',
    879 			]
    880 		);
    881 
    882 		$this->add_hidden_device_controls();
    883 
    884 		$this->end_controls_section();
    885 
    886 		Plugin::$instance->controls_manager->add_custom_attributes_controls( $this );
    887 
    888 		Plugin::$instance->controls_manager->add_custom_css_controls( $this );
    889 	}
    890 
    891 	/**
    892 	 * Render column output in the editor.
    893 	 *
    894 	 * Used to generate the live preview, using a Backbone JavaScript template.
    895 	 *
    896 	 * @since 2.9.0
    897 	 * @access protected
    898 	 */
    899 	protected function content_template() {
    900 		$is_dom_optimization_active = Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' );
    901 		$wrapper_element = $is_dom_optimization_active ? 'widget' : 'column';
    902 
    903 		?>
    904 		<div class="elementor-<?php echo esc_attr( $wrapper_element ); ?>-wrap">
    905 			<div class="elementor-background-overlay"></div>
    906 			<?php if ( ! $is_dom_optimization_active ) { ?>
    907 				<div class="elementor-widget-wrap"></div>
    908 			<?php } ?>
    909 		</div>
    910 		<?php
    911 	}
    912 
    913 	/**
    914 	 * Before column rendering.
    915 	 *
    916 	 * Used to add stuff before the column element.
    917 	 *
    918 	 * @since 1.0.0
    919 	 * @access public
    920 	 */
    921 	public function before_render() {
    922 		$settings = $this->get_settings_for_display();
    923 
    924 		$has_background_overlay = in_array( $settings['background_overlay_background'], [ 'classic', 'gradient' ], true ) ||
    925 								  in_array( $settings['background_overlay_hover_background'], [ 'classic', 'gradient' ], true );
    926 
    927 		$is_dom_optimization_active = Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' );
    928 		$wrapper_attribute_string = $is_dom_optimization_active ? '_widget_wrapper' : '_inner_wrapper';
    929 
    930 		$column_wrap_classes = $is_dom_optimization_active ? [ 'elementor-widget-wrap' ] : [ 'elementor-column-wrap' ];
    931 
    932 		if ( $this->get_children() ) {
    933 			$column_wrap_classes[] = 'elementor-element-populated';
    934 		}
    935 
    936 		$this->add_render_attribute( [
    937 			'_inner_wrapper' => [
    938 				'class' => $column_wrap_classes,
    939 			],
    940 			'_widget_wrapper' => [
    941 				'class' => $is_dom_optimization_active ? $column_wrap_classes : 'elementor-widget-wrap',
    942 			],
    943 			'_background_overlay' => [
    944 				'class' => [ 'elementor-background-overlay' ],
    945 			],
    946 		] );
    947 		?>
    948 		<<?php
    949 		// PHPCS - the method get_html_tag is safe.
    950 		echo $this->get_html_tag(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    951 		?> <?php $this->print_render_attribute_string( '_wrapper' ); ?>>
    952 			<div <?php $this->print_render_attribute_string( $wrapper_attribute_string ); ?>>
    953 		<?php if ( $has_background_overlay ) : ?>
    954 			<div <?php $this->print_render_attribute_string( '_background_overlay' ); ?>></div>
    955 		<?php endif; ?>
    956 		<?php if ( ! $is_dom_optimization_active ) : ?>
    957 			<div <?php $this->print_render_attribute_string( '_widget_wrapper' ); ?>>
    958 		<?php endif; ?>
    959 		<?php
    960 	}
    961 
    962 	/**
    963 	 * After column rendering.
    964 	 *
    965 	 * Used to add stuff after the column element.
    966 	 *
    967 	 * @since 1.0.0
    968 	 * @access public
    969 	 */
    970 	public function after_render() {
    971 		if ( ! Plugin::$instance->experiments->is_feature_active( 'e_dom_optimization' ) ) { ?>
    972 				</div>
    973 		<?php } ?>
    974 			</div>
    975 		</<?php
    976 		// PHPCS - the method get_html_tag is safe.
    977 		echo $this->get_html_tag(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
    978 		<?php
    979 	}
    980 
    981 	/**
    982 	 * Add column render attributes.
    983 	 *
    984 	 * Used to add attributes to the current column wrapper HTML tag.
    985 	 *
    986 	 * @since 1.3.0
    987 	 * @access protected
    988 	 */
    989 	protected function add_render_attributes() {
    990 
    991 		$is_inner = $this->get_data( 'isInner' );
    992 
    993 		$column_type = ! empty( $is_inner ) ? 'inner' : 'top';
    994 
    995 		$settings = $this->get_settings();
    996 
    997 		$this->add_render_attribute(
    998 			'_wrapper', 'class', [
    999 				'elementor-column',
   1000 				'elementor-col-' . $settings['_column_size'],
   1001 				'elementor-' . $column_type . '-column',
   1002 			]
   1003 		);
   1004 
   1005 		parent::add_render_attributes();
   1006 	}
   1007 
   1008 	/**
   1009 	 * Get default child type.
   1010 	 *
   1011 	 * Retrieve the column child type based on element data.
   1012 	 *
   1013 	 * @since 1.0.0
   1014 	 * @access protected
   1015 	 *
   1016 	 * @param array $element_data Element ID.
   1017 	 *
   1018 	 * @return Element_Base Column default child type.
   1019 	 */
   1020 	protected function _get_default_child_type( array $element_data ) {
   1021 		if ( 'section' === $element_data['elType'] ) {
   1022 			return Plugin::$instance->elements_manager->get_element_types( 'section' );
   1023 		}
   1024 
   1025 		return Plugin::$instance->widgets_manager->get_widget_types( $element_data['widgetType'] );
   1026 	}
   1027 
   1028 	/**
   1029 	 * Get HTML tag.
   1030 	 *
   1031 	 * Retrieve the column element HTML tag.
   1032 	 *
   1033 	 * @since 1.5.3
   1034 	 * @access private
   1035 	 *
   1036 	 * @return string Column HTML tag.
   1037 	 */
   1038 	private function get_html_tag() {
   1039 		$html_tag = $this->get_settings( 'html_tag' );
   1040 
   1041 		if ( empty( $html_tag ) ) {
   1042 			$html_tag = 'div';
   1043 		}
   1044 
   1045 		return Utils::validate_html_tag( $html_tag );
   1046 	}
   1047 }