PluginProbe
Elementor Website Builder – more than just a page builder / 3.25.7
Elementor Website Builder – more than just a page builder v3.25.7
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 | modules/nested-tabs/widgets/nested-tabs.php +58 -48 4.2.33.25.7 View file →
@@ -16,16 +16,14 @@
16 16 use Elementor\Plugin;
17 17 use Elementor\Repeater;
18 18
19 19 if ( ! defined( 'ABSPATH' ) ) {
20 - exit; // Exit if accessed directly.
20 + exit; // Exit if accessed directly
21 21 }
22 22
23 23 class NestedTabs extends Widget_Nested_Base {
24 24
25 25 private $tab_item_settings = [];
26 - private $optimized_markup = null;
27 - private $widget_container_selector = '';
28 26
29 27 public function get_name() {
30 28 return 'nested-tabs';
31 29 }
@@ -45,12 +43,8 @@
45 43 public function get_style_depends(): array {
46 44 return [ 'widget-nested-tabs' ];
47 45 }
48 46
49 - public function has_widget_inner_wrapper(): bool {
50 - return ! Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
51 - }
52 -
53 47 public function show_in_panel(): bool {
54 48 return Plugin::$instance->experiments->is_feature_active( 'nested-elements', true );
55 49 }
56 50
@@ -57,13 +51,9 @@
57 51 protected function tab_content_container( int $index ) {
58 52 return [
59 53 'elType' => 'container',
60 54 'settings' => [
61 - '_title' => sprintf(
62 - /* translators: %d: Tab index. */
63 - __( 'Tab #%d', 'elementor' ),
64 - $index
65 - ),
55 + '_title' => sprintf( __( 'Tab #%s', 'elementor' ), $index ),
66 56 'content_width' => 'full',
67 57 ],
68 58 ];
69 59 }
@@ -80,9 +70,8 @@
80 70 return 'tab_title';
81 71 }
82 72
83 73 protected function get_default_children_title() {
84 - /* translators: %d: Tab index. */
85 74 return esc_html__( 'Tab #%d', 'elementor' );
86 75 }
87 76
88 77 protected function get_default_children_placeholder_selector() {
@@ -93,21 +82,16 @@
93 82 return 'elementor-widget-n-tabs';
94 83 }
95 84
96 85 protected function register_controls() {
97 - if ( null === $this->optimized_markup ) {
98 - $this->optimized_markup = Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' ) && ! $this->has_widget_inner_wrapper();
99 - $this->widget_container_selector = $this->optimized_markup ? '' : ' > .elementor-widget-container';
100 - }
101 -
102 86 $start = is_rtl() ? 'right' : 'left';
103 87 $end = is_rtl() ? 'left' : 'right';
104 88 $start_logical = is_rtl() ? 'end' : 'start';
105 89 $end_logical = is_rtl() ? 'start' : 'end';
106 - $heading_selector_non_touch_device = "{{WRAPPER}}.elementor-widget-n-tabs{$this->widget_container_selector} > .e-n-tabs[data-touch-mode='false'] > .e-n-tabs-heading";
107 - $heading_selector_touch_device = "{{WRAPPER}}.elementor-widget-n-tabs{$this->widget_container_selector} > .e-n-tabs[data-touch-mode='true'] > .e-n-tabs-heading";
108 - $heading_selector = "{{WRAPPER}}.elementor-widget-n-tabs{$this->widget_container_selector} > .e-n-tabs > .e-n-tabs-heading";
109 - $content_selector = ":where( {{WRAPPER}}.elementor-widget-n-tabs{$this->widget_container_selector} > .e-n-tabs > .e-n-tabs-content ) > .e-con";
90 + $heading_selector_non_touch_device = '{{WRAPPER}}.elementor-widget-n-tabs > .elementor-widget-container > .e-n-tabs[data-touch-mode="false"] > .e-n-tabs-heading';
91 + $heading_selector_touch_device = '{{WRAPPER}}.elementor-widget-n-tabs > .elementor-widget-container > .e-n-tabs[data-touch-mode="true"] > .e-n-tabs-heading';
92 + $heading_selector = '{{WRAPPER}}.elementor-widget-n-tabs > .elementor-widget-container > .e-n-tabs > .e-n-tabs-heading';
93 + $content_selector = ':where( {{WRAPPER}}.elementor-widget-n-tabs > .elementor-widget-container > .e-n-tabs > .e-n-tabs-content ) > .e-con';
110 94
111 95 $this->start_controls_section( 'section_tabs', [
112 96 'label' => esc_html__( 'Tabs', 'elementor' ),
113 97 ] );
@@ -183,9 +167,9 @@
183 167 'tab_title' => esc_html__( 'Tab #3', 'elementor' ),
184 168 ],
185 169 ],
186 170 'title_field' => '{{{ tab_title }}}',
187 - 'button_text' => esc_html__( 'Add Tab', 'elementor' ),
171 + 'button_text' => 'Add Tab',
188 172 ] );
189 173
190 174 $styling_block_start = '--n-tabs-direction: column; --n-tabs-heading-direction: row; --n-tabs-heading-width: initial; --n-tabs-title-flex-basis: content; --n-tabs-title-flex-shrink: 0;';
191 175 $styling_block_end = '--n-tabs-direction: column-reverse; --n-tabs-heading-direction: row; --n-tabs-heading-width: initial; --n-tabs-title-flex-basis: content; --n-tabs-title-flex-shrink: 0';
@@ -504,9 +488,9 @@
504 488 [
505 489 'name' => 'tabs_title_background_color',
506 490 'types' => [ 'classic', 'gradient' ],
507 491 'exclude' => [ 'image' ],
508 - 'selector' => "{{WRAPPER}}{$this->widget_container_selector} > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title[aria-selected='false']:not( :hover )",
492 + 'selector' => '{{WRAPPER}} > .elementor-widget-container > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title[aria-selected="false"]:not( :hover )',
509 493 'fields_options' => [
510 494 'color' => [
511 495 'label' => esc_html__( 'Background Color', 'elementor' ),
512 496 'selectors' => [
@@ -536,8 +520,9 @@
536 520 $this->add_group_control(
537 521 Group_Control_Box_Shadow::get_type(),
538 522 [
539 523 'name' => 'tabs_title_box_shadow',
524 + 'label' => esc_html__( 'Shadow', 'elementor' ),
540 525 'separator' => 'after',
541 526 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"false\"]:not( :hover )",
542 527 ]
543 528 );
@@ -594,8 +579,9 @@
594 579 $this->add_group_control(
595 580 Group_Control_Box_Shadow::get_type(),
596 581 [
597 582 'name' => 'tabs_title_box_shadow_hover',
583 + 'label' => esc_html__( 'Shadow', 'elementor' ),
598 584 'separator' => 'after',
599 585 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
600 586 ]
601 587 );
@@ -678,8 +664,9 @@
678 664 $this->add_group_control(
679 665 Group_Control_Box_Shadow::get_type(),
680 666 [
681 667 'name' => 'tabs_title_box_shadow_active',
668 + 'label' => esc_html__( 'Shadow', 'elementor' ),
682 669 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"true\"], {$heading_selector_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
683 670 ]
684 671 );
685 672
@@ -758,8 +745,13 @@
758 745 Group_Control_Text_Shadow::get_type(),
759 746 [
760 747 'name' => 'title_text_shadow',
761 748 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"false\"]:not( :hover )",
749 + 'fields_options' => [
750 + 'text_shadow_type' => [
751 + 'label' => esc_html__( 'Shadow', 'elementor' ),
752 + ],
753 + ],
762 754 ]
763 755 );
764 756
765 757 $this->add_group_control(
@@ -766,8 +758,13 @@
766 758 Group_Control_Text_Stroke::get_type(),
767 759 [
768 760 'name' => 'title_text_stroke',
769 761 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"false\"]:not( :hover ) :is( span, a, i )",
762 + 'fields_options' => [
763 + 'text_stroke_type' => [
764 + 'label' => esc_html__( 'Stroke', 'elementor' ),
765 + ],
766 + ],
770 767 ]
771 768 );
772 769
773 770 $this->end_controls_tab();
@@ -794,8 +791,14 @@
794 791 Group_Control_Text_Shadow::get_type(),
795 792 [
796 793 'name' => 'title_text_shadow_hover',
797 794 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
795 + 'fields_options' => [
796 + 'text_shadow_type' => [
797 + 'label' => esc_html__( 'Shadow', 'elementor' ),
798 + ],
799 + ],
800 +
798 801 ]
799 802 );
800 803
801 804 $this->add_group_control(
@@ -802,8 +805,13 @@
802 805 Group_Control_Text_Stroke::get_type(),
803 806 [
804 807 'name' => 'title_text_stroke_hover',
805 808 'selector' => "{$heading_selector_non_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover :is( span, a, i )",
809 + 'fields_options' => [
810 + 'text_stroke_type' => [
811 + 'label' => esc_html__( 'Stroke', 'elementor' ),
812 + ],
813 + ],
806 814 ]
807 815 );
808 816
809 817 $this->end_controls_tab();
@@ -830,8 +838,13 @@
830 838 Group_Control_Text_Shadow::get_type(),
831 839 [
832 840 'name' => 'title_text_shadow_active',
833 841 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"true\"], {$heading_selector_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover",
842 + 'fields_options' => [
843 + 'text_shadow_type' => [
844 + 'label' => esc_html__( 'Shadow', 'elementor' ),
845 + ],
846 + ],
834 847 ]
835 848 );
836 849
837 850 $this->add_group_control(
@@ -838,8 +851,13 @@
838 851 Group_Control_Text_Stroke::get_type(),
839 852 [
840 853 'name' => 'title_text_stroke_active',
841 854 'selector' => "{$heading_selector} > .e-n-tab-title[aria-selected=\"true\"] :is( span, a, i ), {$heading_selector_touch_device} > .e-n-tab-title[aria-selected=\"false\"]:hover :is( span, a, i )",
855 + 'fields_options' => [
856 + 'text_stroke_type' => [
857 + 'label' => esc_html__( 'Stroke', 'elementor' ),
858 + ],
859 + ],
842 860 ]
843 861 );
844 862
845 863 $this->end_controls_tab();
@@ -1075,9 +1093,8 @@
1075 1093 }
1076 1094
1077 1095 $this->add_render_attribute( $setting_key, [
1078 1096 'id' => $item_settings['tab_id'],
1079 - 'data-tab-title-id' => $item_settings['tab_title_id'],
1080 1097 'class' => $css_classes,
1081 1098 'aria-selected' => 1 === $item_settings['tab_count'] ? 'true' : 'false',
1082 1099 'data-tab-index' => $item_settings['tab_count'],
1083 1100 'role' => 'tab',
@@ -1123,9 +1140,9 @@
1123 1140
1124 1141 /**
1125 1142 * Print the content area.
1126 1143 *
1127 - * @param int $index
1144 + * @param int $index
1128 1145 * @param array $item_settings
1129 1146 */
1130 1147 public function print_child( $index, $item_settings = [] ) {
1131 1148 $children = $this->get_children();
@@ -1184,11 +1201,11 @@
1184 1201 <div class="e-n-tabs-heading" role="tablist">
1185 1202 <?php
1186 1203 foreach ( $settings['tabs'] as $index => $item ) {
1187 1204 $tab_count = $index + 1;
1188 - $tab_title_id = 'e-n-tab-title-' . $widget_number . $tab_count;
1205 +
1189 1206 $tab_id = empty( $item['element_id'] )
1190 - ? $tab_title_id
1207 + ? 'e-n-tab-title-' . $widget_number . $tab_count
1191 1208 : $item['element_id'];
1192 1209
1193 1210 $item_settings = [
1194 1211 'index' => $index,
@@ -1193,9 +1210,8 @@
1193 1210 $item_settings = [
1194 1211 'index' => $index,
1195 1212 'tab_count' => $tab_count,
1196 1213 'tab_id' => $tab_id,
1197 - 'tab_title_id' => $tab_title_id,
1198 1214 'container_id' => 'e-n-tab-content-' . $widget_number . $tab_count,
1199 1215 'widget_number' => $widget_number,
1200 1216 'item' => $item,
1201 1217 'settings' => $settings,
@@ -1214,13 +1230,17 @@
1214 1230 <?php
1215 1231 }
1216 1232
1217 1233 protected function get_initial_config(): array {
1218 - return array_merge( parent::get_initial_config(), [
1219 - 'support_improved_repeaters' => true,
1220 - 'target_container' => [ '.e-n-tabs-heading' ],
1221 - 'node' => 'button',
1222 - ] );
1234 + if ( Plugin::$instance->experiments->is_feature_active( 'e_nested_atomic_repeaters' ) ) {
1235 + return array_merge( parent::get_initial_config(), [
1236 + 'support_improved_repeaters' => true,
1237 + 'target_container' => [ '.e-n-tabs-heading' ],
1238 + 'node' => 'button',
1239 + ] );
1240 + }
1241 +
1242 + return parent::get_initial_config();
1223 1243 }
1224 1244
1225 1245 protected function content_template_single_repeater_item() {
1226 1246 ?>
@@ -1261,12 +1281,11 @@
1261 1281 private function content_template_single_item( $tab_index, $item, $element_uid, $hover_animation_class ) {
1262 1282 ?>
1263 1283 <#
1264 1284 const tabCount = tabIndex + 1,
1265 - tabTitleId = 'e-n-tab-title-' + elementUid + tabCount,
1266 1285 tabId = item.element_id
1267 1286 ? item.element_id
1268 - : tabTitleId,
1287 + : 'e-n-tab-title-' + elementUid + ( tabIndex + 1 ),
1269 1288 tabUid = elementUid + tabCount,
1270 1289 tabIcon = elementor.helpers.renderIcon( view, item.tab_icon, { 'aria-hidden': true }, 'i' , 'object' ),
1271 1290 activeTabIcon = item.tab_icon_active.value
1272 1291 ? elementor.helpers.renderIcon( view, item.tab_icon_active, { 'aria-hidden': true }, 'i' , 'object' )
@@ -1274,9 +1293,8 @@
1274 1293 escapedHoverAnimationClass = _.escape( hoverAnimationClass );
1275 1294
1276 1295 view.addRenderAttribute( 'tab-title', {
1277 1296 'id': tabId,
1278 - 'data-tab-title-id': tabTitleId,
1279 1297 'class': [ 'e-n-tab-title',escapedHoverAnimationClass ],
1280 1298 'data-tab-index': tabCount,
1281 1299 'role': 'tab',
1282 1300 'aria-selected': 1 === tabCount ? 'true' : 'false',
@@ -1288,20 +1306,11 @@
1288 1306 view.addRenderAttribute( 'tab-title-text', {
1289 1307 'class': [ 'e-n-tab-title-text' ],
1290 1308 'data-binding-type': 'repeater-item',
1291 1309 'data-binding-repeater-name': 'tabs',
1292 - 'data-binding-setting': [ 'tab_title', 'element_id' ],
1310 + 'data-binding-setting': [ 'tab_title' ],
1293 1311 'data-binding-index': tabCount,
1294 - 'data-binding-config': JSON.stringify({
1295 - 'element_id': {
1296 - attr: 'id',
1297 - selector: 'button',
1298 - editType: 'attribute',
1299 - },
1300 - 'tab_title': {
1301 - editType: 'text',
1302 - },
1303 - }),
1312 + 'data-binding-dynamic': 'true',
1304 1313 }, null, true );
1305 1314
1306 1315 view.addRenderAttribute( 'tab-icon', {
1307 1316 'class': [ 'e-n-tab-icon' ],
@@ -1306,8 +1315,9 @@
1306 1315 view.addRenderAttribute( 'tab-icon', {
1307 1316 'class': [ 'e-n-tab-icon' ],
1308 1317 'data-binding-type': 'repeater-item',
1309 1318 'data-binding-repeater-name': 'tabs',
1319 + 'data-binding-setting': [ 'tab_icon', 'tab_icon_active' ],
1310 1320 'data-binding-index': tabCount,
1311 1321 }, null, true );
1312 1322 #>
1313 1323