PluginProbe
Elementor Website Builder – more than just a page builder / 3.17.2
Elementor Website Builder – more than just a page builder v3.17.2
4.3.1 4.3.0 4.3.0-beta3 4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 All 454 releases
← All changes | includes/widgets/traits/button-trait.php +87 -192 4.3.13.17.2 View file →
@@ -10,12 +10,11 @@
10 10 use Elementor\Group_Control_Text_Shadow;
11 11 use Elementor\Group_Control_Typography;
12 12 use Elementor\Icons_Manager;
13 13 use Elementor\Widget_Base;
14 -use Elementor\Plugin;
15 14
16 15 if ( ! defined( 'ABSPATH' ) ) {
17 - exit; // Exit if accessed directly.
16 + exit; // Exit if accessed directly
18 17 }
19 18
20 19 trait Button_Trait {
21 20 /**
@@ -47,8 +46,10 @@
47 46 *
48 47 * @type array $section_condition Set of conditions to hide the controls.
49 48 * @type string $button_text Text contained in button.
50 49 * @type string $text_control_label Name for the label of the text control.
50 + * @type string $alignment_control_prefix_class Prefix class name for the button alignment control.
51 + * @type string $alignment_default Default alignment for the button.
51 52 * @type array $icon_exclude_inline_options Set of icon types to exclude from icon controls.
52 53 * }
53 54 */
54 55 protected function register_button_content_controls( $args = [] ) {
@@ -55,8 +56,10 @@
55 56 $default_args = [
56 57 'section_condition' => [],
57 58 'button_default_text' => esc_html__( 'Click here', 'elementor' ),
58 59 'text_control_label' => esc_html__( 'Text', 'elementor' ),
60 + 'alignment_control_prefix_class' => 'elementor%s-align-',
61 + 'alignment_default' => '',
59 62 'icon_exclude_inline_options' => [],
60 63 ];
61 64
62 65 $args = wp_parse_args( $args, $default_args );
@@ -107,8 +110,37 @@
107 110 'condition' => $args['section_condition'],
108 111 ]
109 112 );
110 113
114 + $this->add_responsive_control(
115 + 'align',
116 + [
117 + 'label' => esc_html__( 'Alignment', 'elementor' ),
118 + 'type' => Controls_Manager::CHOOSE,
119 + 'options' => [
120 + 'left' => [
121 + 'title' => esc_html__( 'Left', 'elementor' ),
122 + 'icon' => 'eicon-text-align-left',
123 + ],
124 + 'center' => [
125 + 'title' => esc_html__( 'Center', 'elementor' ),
126 + 'icon' => 'eicon-text-align-center',
127 + ],
128 + 'right' => [
129 + 'title' => esc_html__( 'Right', 'elementor' ),
130 + 'icon' => 'eicon-text-align-right',
131 + ],
132 + 'justify' => [
133 + 'title' => esc_html__( 'Justified', 'elementor' ),
134 + 'icon' => 'eicon-text-align-justify',
135 + ],
136 + ],
137 + 'prefix_class' => $args['alignment_control_prefix_class'],
138 + 'default' => $args['alignment_default'],
139 + 'condition' => $args['section_condition'],
140 + ]
141 + );
142 +
111 143 $this->add_control(
112 144 'size',
113 145 [
114 146 'label' => esc_html__( 'Size', 'elementor' ),
@@ -115,9 +147,9 @@
115 147 'type' => Controls_Manager::SELECT,
116 148 'default' => 'sm',
117 149 'options' => self::get_button_sizes(),
118 150 'style_transfer' => true,
119 - 'condition' => array_merge( $args['section_condition'], [ 'size[value]!' => 'sm' ] ), // a workaround to hide the control, unless it's in use (not default).
151 + 'condition' => $args['section_condition'],
120 152 ]
121 153 );
122 154
123 155 $this->add_control(
@@ -136,35 +168,15 @@
136 168 $this->add_control(
137 169 'icon_align',
138 170 [
139 171 'label' => esc_html__( 'Icon Position', 'elementor' ),
140 - 'type' => Controls_Manager::CHOOSE,
141 - 'default' => is_rtl() ? 'row-reverse' : 'row',
172 + 'type' => Controls_Manager::SELECT,
173 + 'default' => 'left',
142 174 'options' => [
143 - 'row' => [
144 - 'title' => esc_html__( 'Start', 'elementor' ),
145 - 'icon' => 'eicon-h-align-left',
146 - ],
147 - 'row-reverse' => [
148 - 'title' => esc_html__( 'End', 'elementor' ),
149 - 'icon' => 'eicon-h-align-right',
150 - ],
175 + 'left' => esc_html__( 'Before', 'elementor' ),
176 + 'right' => esc_html__( 'After', 'elementor' ),
151 177 ],
152 - 'classes' => 'elementor-control-start-end',
153 - 'selectors_dictionary' => [
154 - 'left' => is_rtl() ? 'row-reverse' : 'row',
155 - 'right' => is_rtl() ? 'row' : 'row-reverse',
156 - ],
157 - 'selectors' => [
158 - '{{WRAPPER}} .elementor-button-content-wrapper' => 'flex-direction: {{VALUE}};',
159 - ],
160 - 'condition' => array_merge(
161 - $args['section_condition'],
162 - [
163 - 'text!' => '',
164 - 'selected_icon[value]!' => '',
165 - ]
166 - ),
178 + 'condition' => array_merge( $args['section_condition'], [ 'selected_icon[value]!' => '' ] ),
167 179 ]
168 180 );
169 181
170 182 $this->add_control(
@@ -171,34 +183,32 @@
171 183 'icon_indent',
172 184 [
173 185 'label' => esc_html__( 'Icon Spacing', 'elementor' ),
174 186 'type' => Controls_Manager::SLIDER,
175 - 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
176 187 'range' => [
177 188 'px' => [
178 189 'max' => 50,
179 190 ],
180 - 'em' => [
181 - 'max' => 5,
182 - ],
183 - 'rem' => [
184 - 'max' => 5,
185 - ],
186 191 ],
187 192 'selectors' => [
188 - '{{WRAPPER}} .elementor-button .elementor-button-content-wrapper' => 'gap: {{SIZE}}{{UNIT}};',
193 + '{{WRAPPER}} .elementor-button .elementor-align-icon-right' => 'margin-left: {{SIZE}}{{UNIT}};',
194 + '{{WRAPPER}} .elementor-button .elementor-align-icon-left' => 'margin-right: {{SIZE}}{{UNIT}};',
189 195 ],
190 - 'condition' => array_merge(
191 - $args['section_condition'],
192 - [
193 - 'text!' => '',
194 - 'selected_icon[value]!' => '',
195 - ]
196 - ),
196 + 'condition' => $args['section_condition'],
197 197 ]
198 198 );
199 199
200 200 $this->add_control(
201 + 'view',
202 + [
203 + 'label' => esc_html__( 'View', 'elementor' ),
204 + 'type' => Controls_Manager::HIDDEN,
205 + 'default' => 'traditional',
206 + 'condition' => $args['section_condition'],
207 + ]
208 + );
209 +
210 + $this->add_control(
201 211 'button_css_id',
202 212 [
203 213 'label' => esc_html__( 'Button ID', 'elementor' ),
204 214 'type' => Controls_Manager::TEXT,
@@ -210,10 +220,9 @@
210 220 ],
211 221 'default' => '',
212 222 'title' => esc_html__( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'elementor' ),
213 223 'description' => sprintf(
214 - /* translators: 1: `<code>` opening tag, 2: `</code>` closing tag. */
215 - esc_html__( 'Please make sure the ID is unique and not used elsewhere on the page. This field allows %1$sA-z 0-9%2$s & underscore chars without spaces.', 'elementor' ),
224 + esc_html__( 'Please make sure the ID is unique and not used elsewhere on the page this form is displayed. This field allows %1$sA-z 0-9%2$s & underscore chars without spaces.', 'elementor' ),
216 225 '<code>',
217 226 '</code>'
218 227 ),
219 228 'separator' => 'before',
@@ -221,91 +230,15 @@
221 230 ]
222 231 );
223 232 }
224 233
225 - /**
226 - * @since 3.4.0
227 - *
228 - * @param array $args {
229 - * An array of values for the button adjustments.
230 - *
231 - * @type array $section_condition Set of conditions to hide the controls.
232 - * @type string $alignment_default Default position for the button.
233 - * @type string $alignment_control_prefix_class Prefix class name for the button position control.
234 - * @type string $content_alignment_default Default alignment for the button content.
235 - * }
236 - */
237 234 protected function register_button_style_controls( $args = [] ) {
238 235 $default_args = [
239 236 'section_condition' => [],
240 - 'alignment_default' => '',
241 - 'alignment_control_prefix_class' => 'elementor%s-align-',
242 - 'content_alignment_default' => '',
243 237 ];
244 238
245 239 $args = wp_parse_args( $args, $default_args );
246 240
247 - $this->add_responsive_control(
248 - 'align',
249 - [
250 - 'label' => esc_html__( 'Position', 'elementor' ),
251 - 'type' => Controls_Manager::CHOOSE,
252 - 'options' => [
253 - 'left' => [
254 - 'title' => esc_html__( 'Left', 'elementor' ),
255 - 'icon' => 'eicon-h-align-left',
256 - ],
257 - 'center' => [
258 - 'title' => esc_html__( 'Center', 'elementor' ),
259 - 'icon' => 'eicon-h-align-center',
260 - ],
261 - 'right' => [
262 - 'title' => esc_html__( 'Right', 'elementor' ),
263 - 'icon' => 'eicon-h-align-right',
264 - ],
265 - 'justify' => [
266 - 'title' => esc_html__( 'Stretch', 'elementor' ),
267 - 'icon' => 'eicon-h-align-stretch',
268 - ],
269 - ],
270 - 'prefix_class' => $args['alignment_control_prefix_class'],
271 - 'default' => $args['alignment_default'],
272 - 'condition' => $args['section_condition'],
273 - ]
274 - );
275 -
276 - $this->add_responsive_control(
277 - 'content_align',
278 - [
279 - 'label' => esc_html__( 'Alignment', 'elementor' ),
280 - 'type' => Controls_Manager::CHOOSE,
281 - 'options' => [
282 - 'start' => [
283 - 'title' => esc_html__( 'Start', 'elementor' ),
284 - 'icon' => 'eicon-text-align-left',
285 - ],
286 - 'center' => [
287 - 'title' => esc_html__( 'Center', 'elementor' ),
288 - 'icon' => 'eicon-text-align-center',
289 - ],
290 - 'end' => [
291 - 'title' => esc_html__( 'End', 'elementor' ),
292 - 'icon' => 'eicon-text-align-right',
293 - ],
294 - 'space-between' => [
295 - 'title' => esc_html__( 'Space between', 'elementor' ),
296 - 'icon' => 'eicon-text-align-justify',
297 - ],
298 - ],
299 - 'default' => $args['content_alignment_default'],
300 - 'classes' => 'elementor-control-start-end',
301 - 'selectors' => [
302 - '{{WRAPPER}} .elementor-button .elementor-button-content-wrapper' => 'justify-content: {{VALUE}};',
303 - ],
304 - 'condition' => array_merge( $args['section_condition'], [ 'align' => 'justify' ] ),
305 - ]
306 - );
307 -
308 241 $this->add_group_control(
309 242 Group_Control_Typography::get_type(),
310 243 [
311 244 'name' => 'typography',
@@ -371,17 +304,8 @@
371 304 'condition' => $args['section_condition'],
372 305 ]
373 306 );
374 307
375 - $this->add_group_control(
376 - Group_Control_Box_Shadow::get_type(),
377 - [
378 - 'name' => 'button_box_shadow',
379 - 'selector' => '{{WRAPPER}} .elementor-button',
380 - 'condition' => $args['section_condition'],
381 - ]
382 - );
383 -
384 308 $this->end_controls_tab();
385 309
386 310 $this->start_controls_tab(
387 311 'tab_button_hover',
@@ -424,8 +348,11 @@
424 348 'button_hover_border_color',
425 349 [
426 350 'label' => esc_html__( 'Border Color', 'elementor' ),
427 351 'type' => Controls_Manager::COLOR,
352 + 'condition' => [
353 + 'border_border!' => '',
354 + ],
428 355 'selectors' => [
429 356 '{{WRAPPER}} .elementor-button:hover, {{WRAPPER}} .elementor-button:focus' => 'border-color: {{VALUE}};',
430 357 ],
431 358 'condition' => $args['section_condition'],
@@ -431,33 +358,9 @@
431 358 'condition' => $args['section_condition'],
432 359 ]
433 360 );
434 361
435 - $this->add_group_control(
436 - Group_Control_Box_Shadow::get_type(),
437 - [
438 - 'name' => 'button_hover_box_shadow',
439 - 'selector' => '{{WRAPPER}} .elementor-button:hover, {{WRAPPER}} .elementor-button:focus',
440 - 'condition' => $args['section_condition'],
441 - ]
442 - );
443 -
444 362 $this->add_control(
445 - 'button_hover_transition_duration',
446 - [
447 - 'label' => esc_html__( 'Transition Duration', 'elementor' ),
448 - 'type' => Controls_Manager::SLIDER,
449 - 'size_units' => [ 's', 'ms', 'custom' ],
450 - 'default' => [
451 - 'unit' => 's',
452 - ],
453 - 'selectors' => [
454 - '{{WRAPPER}} .elementor-button' => 'transition-duration: {{SIZE}}{{UNIT}};',
455 - ],
456 - ]
457 - );
458 -
459 - $this->add_control(
460 363 'hover_animation',
461 364 [
462 365 'label' => esc_html__( 'Hover Animation', 'elementor' ),
463 366 'type' => Controls_Manager::HOVER_ANIMATION,
@@ -491,8 +394,17 @@
491 394 'condition' => $args['section_condition'],
492 395 ]
493 396 );
494 397
398 + $this->add_group_control(
399 + Group_Control_Box_Shadow::get_type(),
400 + [
401 + 'name' => 'button_box_shadow',
402 + 'selector' => '{{WRAPPER}} .elementor-button',
403 + 'condition' => $args['section_condition'],
404 + ]
405 + );
406 +
495 407 $this->add_responsive_control(
496 408 'text_padding',
497 409 [
498 410 'label' => esc_html__( 'Padding', 'elementor' ),
@@ -516,9 +428,9 @@
516 428 *
517 429 * @since 3.4.0
518 430 * @access protected
519 431 */
520 - protected function render_button( ?Widget_Base $instance = null ) {
432 + protected function render_button( Widget_Base $instance = null ) {
521 433 if ( empty( $instance ) ) {
522 434 $instance = $this;
523 435 }
524 436
@@ -523,14 +435,8 @@
523 435 }
524 436
525 437 $settings = $instance->get_settings_for_display();
526 438
527 - if ( empty( $settings['text'] ) && empty( $settings['selected_icon']['value'] ) ) {
528 - return;
529 - }
530 -
531 - $optimized_markup = Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
532 -
533 439 $instance->add_render_attribute( 'wrapper', 'class', 'elementor-button-wrapper' );
534 440
535 441 $instance->add_render_attribute( 'button', 'class', 'elementor-button' );
536 442
@@ -546,10 +452,8 @@
546 452 }
547 453
548 454 if ( ! empty( $settings['size'] ) ) {
549 455 $instance->add_render_attribute( 'button', 'class', 'elementor-size-' . $settings['size'] );
550 - } else {
551 - $instance->add_render_attribute( 'button', 'class', 'elementor-size-sm' ); // BC, to make sure the class is always present
552 456 }
553 457
554 458 if ( ! empty( $settings['hover_animation'] ) ) {
555 459 $instance->add_render_attribute( 'button', 'class', 'elementor-animation-' . $settings['hover_animation'] );
@@ -554,17 +458,13 @@
554 458 if ( ! empty( $settings['hover_animation'] ) ) {
555 459 $instance->add_render_attribute( 'button', 'class', 'elementor-animation-' . $settings['hover_animation'] );
556 460 }
557 461 ?>
558 - <?php if ( ! $optimized_markup ) : ?>
559 462 <div <?php $instance->print_render_attribute_string( 'wrapper' ); ?>>
560 - <?php endif; ?>
561 463 <a <?php $instance->print_render_attribute_string( 'button' ); ?>>
562 464 <?php $this->render_text( $instance ); ?>
563 465 </a>
564 - <?php if ( ! $optimized_markup ) : ?>
565 466 </div>
566 - <?php endif; ?>
567 467 <?php
568 468 }
569 469
570 470 /**
@@ -577,20 +477,14 @@
577 477 */
578 478 protected function content_template() {
579 479 ?>
580 480 <#
581 - if ( '' === settings.text && '' === settings.selected_icon.value ) {
582 - return;
583 - }
584 -
585 - const optimized_markup = elementorCommon.config.experimentalFeatures.e_optimized_markup;
586 -
587 481 view.addRenderAttribute( 'wrapper', 'class', 'elementor-button-wrapper' );
588 482
589 483 view.addRenderAttribute( 'button', 'class', 'elementor-button' );
590 484
591 - if ( '' !== settings.link?.url ) {
592 - view.addRenderAttribute( 'button', 'href', elementor.helpers.sanitizeUrl( settings.link?.url ) );
485 + if ( '' !== settings.link.url ) {
486 + view.addRenderAttribute( 'button', 'href', settings.link.url );
593 487 view.addRenderAttribute( 'button', 'class', 'elementor-button-link' );
594 488 } else {
595 489 view.addRenderAttribute( 'button', 'role', 'button' );
596 490 }
@@ -606,21 +500,18 @@
606 500 if ( '' !== settings.hover_animation ) {
607 501 view.addRenderAttribute( 'button', 'class', 'elementor-animation-' + settings.hover_animation );
608 502 }
609 503
610 - view.addRenderAttribute( 'icon', 'class', 'elementor-button-icon' );
611 504 view.addRenderAttribute( 'text', 'class', 'elementor-button-text' );
612 505 view.addInlineEditingAttributes( 'text', 'none' );
613 506 var iconHTML = elementor.helpers.renderIcon( view, settings.selected_icon, { 'aria-hidden': true }, 'i' , 'object' ),
614 507 migrated = elementor.helpers.isIconMigrated( settings, 'selected_icon' );
615 508 #>
616 - <# if ( ! optimized_markup ) { #>
617 509 <div {{{ view.getRenderAttributeString( 'wrapper' ) }}}>
618 - <# } #>
619 510 <a {{{ view.getRenderAttributeString( 'button' ) }}}>
620 511 <span class="elementor-button-content-wrapper">
621 512 <# if ( settings.icon || settings.selected_icon ) { #>
622 - <span {{{ view.getRenderAttributeString( 'icon' ) }}}>
513 + <span class="elementor-button-icon elementor-align-icon-{{ settings.icon_align }}">
623 514 <# if ( ( migrated || ! settings.icon ) && iconHTML.rendered ) { #>
624 515 {{{ iconHTML.value }}}
625 516 <# } else { #>
626 517 <i class="{{ settings.icon }}" aria-hidden="true"></i>
@@ -626,16 +517,12 @@
626 517 <i class="{{ settings.icon }}" aria-hidden="true"></i>
627 518 <# } #>
628 519 </span>
629 520 <# } #>
630 - <# if ( settings.text ) { #>
631 - <span {{{ view.getRenderAttributeString( 'text' ) }}}>{{ settings.text }}</span>
632 - <# } #>
521 + <span {{{ view.getRenderAttributeString( 'text' ) }}}>{{{ settings.text }}}</span>
633 522 </span>
634 523 </a>
635 - <# if ( ! optimized_markup ) { #>
636 524 </div>
637 - <# } #>
638 525 <?php
639 526 }
640 527
641 528 /**
@@ -647,9 +534,9 @@
647 534 *
648 535 * @since 3.4.0
649 536 * @access protected
650 537 */
651 - protected function render_text( ?Widget_Base $instance = null ) {
538 + protected function render_text( Widget_Base $instance = null ) {
652 539 // The default instance should be `$this` (a Button widget), unless the Trait is being used from outside of a widget (e.g. `Skin_Base`) which should pass an `$instance`.
653 540 if ( empty( $instance ) ) {
654 541 $instance = $this;
655 542 }
@@ -658,14 +545,24 @@
658 545
659 546 $migrated = isset( $settings['__fa4_migrated']['selected_icon'] );
660 547 $is_new = empty( $settings['icon'] ) && Icons_Manager::is_migration_allowed();
661 548
549 + if ( ! $is_new && empty( $settings['icon_align'] ) ) {
550 + // @todo: remove when deprecated
551 + // added as bc in 2.6
552 + //old default
553 + $settings['icon_align'] = $instance->get_settings( 'icon_align' );
554 + }
555 +
662 556 $instance->add_render_attribute( [
663 557 'content-wrapper' => [
664 558 'class' => 'elementor-button-content-wrapper',
665 559 ],
666 - 'icon' => [
667 - 'class' => 'elementor-button-icon',
560 + 'icon-align' => [
561 + 'class' => [
562 + 'elementor-button-icon',
563 + 'elementor-align-icon-' . $settings['icon_align'],
564 + ],
668 565 ],
669 566 'text' => [
670 567 'class' => 'elementor-button-text',
671 568 ],
@@ -671,13 +568,13 @@
671 568 ],
672 569 ] );
673 570
674 571 // TODO: replace the protected with public
675 - // $instance->add_inline_editing_attributes( 'text', 'none' );
572 + //$instance->add_inline_editing_attributes( 'text', 'none' );
676 573 ?>
677 574 <span <?php $instance->print_render_attribute_string( 'content-wrapper' ); ?>>
678 575 <?php if ( ! empty( $settings['icon'] ) || ! empty( $settings['selected_icon']['value'] ) ) : ?>
679 - <span <?php $instance->print_render_attribute_string( 'icon' ); ?>>
576 + <span <?php $instance->print_render_attribute_string( 'icon-align' ); ?>>
680 577 <?php if ( $is_new || $migrated ) :
681 578 Icons_Manager::render_icon( $settings['selected_icon'], [ 'aria-hidden' => 'true' ] );
682 579 else : ?>
683 580 <i class="<?php echo esc_attr( $settings['icon'] ); ?>" aria-hidden="true"></i>
@@ -683,11 +580,9 @@
683 580 <i class="<?php echo esc_attr( $settings['icon'] ); ?>" aria-hidden="true"></i>
684 581 <?php endif; ?>
685 582 </span>
686 583 <?php endif; ?>
687 - <?php if ( ! empty( $settings['text'] ) ) : ?>
688 - <span <?php $instance->print_render_attribute_string( 'text' ); ?>><?php echo wp_kses_post( $settings['text'] ); ?></span>
689 - <?php endif; ?>
584 + <span <?php $instance->print_render_attribute_string( 'text' ); ?>><?php $this->print_unescaped_setting( 'text' ); ?></span>
690 585 </span>
691 586 <?php
692 587 }
693 588