Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/elementor/includes/widgets/heading.php
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
<?php
2
+
namespace Elementor;
3
+
4
+
if ( ! defined( 'ABSPATH' ) ) {
5
+
exit; // Exit if accessed directly.
6
+
}
7
+
8
+
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
9
+
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
10
+
use Elementor\Modules\ContentSanitizer\Interfaces\Sanitizable;
11
+
use Elementor\Core\Utils\Hints;
12
+
use Elementor\Core\Admin\Admin_Notices;
13
+
use Elementor\Modules\Promotions\Controls\Promotion_Control;
14
+
15
+
/**
16
+
* Elementor heading widget.
17
+
*
18
+
* Elementor widget that displays an eye-catching headlines.
19
+
*
20
+
* @since 1.0.0
21
+
*/
22
+
class Widget_Heading extends Widget_Base implements Sanitizable {
23
+
24
+
/**
25
+
* Get widget name.
26
+
*
27
+
* Retrieve heading widget name.
28
+
*
29
+
* @since 1.0.0
30
+
* @access public
31
+
*
32
+
* @return string Widget name.
33
+
*/
34
+
public function get_name() {
35
+
return 'heading';
36
+
}
37
+
38
+
/**
39
+
* Get widget title.
40
+
*
41
+
* Retrieve heading widget title.
42
+
*
43
+
* @since 1.0.0
44
+
* @access public
45
+
*
46
+
* @return string Widget title.
47
+
*/
48
+
public function get_title() {
49
+
return esc_html__( 'Heading', 'elementor' );
50
+
}
51
+
52
+
/**
53
+
* Get widget icon.
54
+
*
55
+
* Retrieve heading widget icon.
56
+
*
57
+
* @since 1.0.0
58
+
* @access public
59
+
*
60
+
* @return string Widget icon.
61
+
*/
62
+
public function get_icon() {
63
+
return 'eicon-t-letter';
64
+
}
65
+
66
+
/**
67
+
* Get widget categories.
68
+
*
69
+
* Retrieve the list of categories the heading widget belongs to.
70
+
*
71
+
* Used to determine where to display the widget in the editor.
72
+
*
73
+
* @since 2.0.0
74
+
* @access public
75
+
*
76
+
* @return array Widget categories.
77
+
*/
78
+
public function get_categories() {
79
+
return [ 'basic' ];
80
+
}
81
+
82
+
/**
83
+
* Get widget keywords.
84
+
*
85
+
* Retrieve the list of keywords the widget belongs to.
86
+
*
87
+
* @since 2.1.0
88
+
* @access public
89
+
*
90
+
* @return array Widget keywords.
91
+
*/
92
+
public function get_keywords() {
93
+
return [ 'heading', 'title', 'text' ];
94
+
}
95
+
96
+
protected function is_dynamic_content(): bool {
97
+
return false;
98
+
}
99
+
100
+
/**
101
+
* Get style dependencies.
102
+
*
103
+
* Retrieve the list of style dependencies the widget requires.
104
+
*
105
+
* @since 3.24.0
106
+
* @access public
107
+
*
108
+
* @return array Widget style dependencies.
109
+
*/
110
+
public function get_style_depends(): array {
111
+
return [ 'widget-heading' ];
112
+
}
113
+
114
+
public function has_widget_inner_wrapper(): bool {
115
+
return ! Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
116
+
}
117
+
118
+
/**
119
+
* Remove data attributes from the html.
120
+
*
121
+
* @param string $content Heading title.
122
+
* @return string
123
+
*/
124
+
public function sanitize( $content ): string {
125
+
$allowed_tags = wp_kses_allowed_html( 'post' );
126
+
$allowed_tags_for_heading = [];
127
+
$non_allowed_tags = [ 'img' ];
128
+
129
+
foreach ( $allowed_tags as $tag => $attributes ) {
130
+
if ( in_array( $tag, $non_allowed_tags, true ) ) {
131
+
continue;
132
+
}
133
+
134
+
$filtered_attributes = array_filter( $attributes, function( $attribute ) {
135
+
return ! substr( $attribute, 0, 5 ) === 'data-';
136
+
}, ARRAY_FILTER_USE_KEY );
137
+
138
+
$allowed_tags_for_heading[ $tag ] = $filtered_attributes;
139
+
}
140
+
141
+
return wp_kses( $content, $allowed_tags_for_heading );
142
+
}
143
+
144
+
/**
145
+
* Get widget upsale data.
146
+
*
147
+
* Retrieve the widget promotion data.
148
+
*
149
+
* @since 3.18.0
150
+
* @access protected
151
+
*
152
+
* @return array Widget promotion data.
153
+
*/
154
+
protected function get_upsale_data() {
155
+
return [
156
+
'condition' => ! Utils::has_pro(),
157
+
'image' => esc_url( ELEMENTOR_ASSETS_URL . 'images/go-pro.svg' ),
158
+
'image_alt' => esc_attr__( 'Upgrade', 'elementor' ),
159
+
'description' => esc_html__( 'Create captivating headings that rotate with the Animated Headline Widget.', 'elementor' ),
160
+
'upgrade_url' => esc_url( 'https://go.elementor.com/go-pro-heading-widget/' ),
161
+
'upgrade_text' => esc_html__( 'Upgrade Now', 'elementor' ),
162
+
];
163
+
}
164
+
165
+
/**
166
+
* Register heading widget controls.
167
+
*
168
+
* Adds different input fields to allow the user to change and customize the widget settings.
169
+
*
170
+
* @since 3.1.0
171
+
* @access protected
172
+
*/
173
+
protected function register_controls() {
174
+
$this->start_controls_section(
175
+
'section_title',
176
+
[
177
+
'label' => esc_html__( 'Heading', 'elementor' ),
178
+
]
179
+
);
180
+
181
+
$this->add_control(
182
+
'title',
183
+
[
184
+
'label' => esc_html__( 'Title', 'elementor' ),
185
+
'type' => Controls_Manager::TEXTAREA,
186
+
'ai' => [
187
+
'type' => 'text',
188
+
],
189
+
'dynamic' => [
190
+
'active' => true,
191
+
],
192
+
'placeholder' => esc_html__( 'Enter your title', 'elementor' ),
193
+
'default' => esc_html__( 'Add Your Heading Text Here', 'elementor' ),
194
+
]
195
+
);
196
+
197
+
$this->add_control(
198
+
'link',
199
+
[
200
+
'label' => esc_html__( 'Link', 'elementor' ),
201
+
'type' => Controls_Manager::URL,
202
+
'dynamic' => [
203
+
'active' => true,
204
+
],
205
+
'default' => [
206
+
'url' => '',
207
+
],
208
+
]
209
+
);
210
+
211
+
$this->add_control(
212
+
'size',
213
+
[
214
+
'label' => esc_html__( 'Size', 'elementor' ),
215
+
'type' => Controls_Manager::SELECT,
216
+
'options' => [
217
+
'default' => esc_html__( 'Default', 'elementor' ),
218
+
'small' => esc_html__( 'Small', 'elementor' ),
219
+
'medium' => esc_html__( 'Medium', 'elementor' ),
220
+
'large' => esc_html__( 'Large', 'elementor' ),
221
+
'xl' => esc_html__( 'XL', 'elementor' ),
222
+
'xxl' => esc_html__( 'XXL', 'elementor' ),
223
+
],
224
+
'default' => 'default',
225
+
'condition' => [
226
+
'size!' => 'default', // a workaround to hide the control, unless it's in use (not default).
227
+
],
228
+
]
229
+
);
230
+
231
+
$this->add_control(
232
+
'header_size',
233
+
[
234
+
'label' => esc_html__( 'HTML Tag', 'elementor' ),
235
+
'type' => Controls_Manager::SELECT,
236
+
'options' => [
237
+
'h1' => 'H1',
238
+
'h2' => 'H2',
239
+
'h3' => 'H3',
240
+
'h4' => 'H4',
241
+
'h5' => 'H5',
242
+
'h6' => 'H6',
243
+
'div' => 'div',
244
+
'span' => 'span',
245
+
'p' => 'p',
246
+
],
247
+
'default' => 'h2',
248
+
]
249
+
);
250
+
251
+
$this->maybe_add_ally_heading_hint();
252
+
253
+
$this->end_controls_section();
254
+
255
+
$this->start_controls_section(
256
+
'section_title_style',
257
+
[
258
+
'label' => esc_html__( 'Heading', 'elementor' ),
259
+
'tab' => Controls_Manager::TAB_STYLE,
260
+
]
261
+
);
262
+
263
+
$this->add_responsive_control(
264
+
'align',
265
+
[
266
+
'label' => esc_html__( 'Alignment', 'elementor' ),
267
+
'type' => Controls_Manager::CHOOSE,
268
+
'options' => [
269
+
'start' => [
270
+
'title' => esc_html__( 'Start', 'elementor' ),
271
+
'icon' => 'eicon-text-align-left',
272
+
],
273
+
'center' => [
274
+
'title' => esc_html__( 'Center', 'elementor' ),
275
+
'icon' => 'eicon-text-align-center',
276
+
],
277
+
'end' => [
278
+
'title' => esc_html__( 'End', 'elementor' ),
279
+
'icon' => 'eicon-text-align-right',
280
+
],
281
+
'justify' => [
282
+
'title' => esc_html__( 'Justified', 'elementor' ),
283
+
'icon' => 'eicon-text-align-justify',
284
+
],
285
+
],
286
+
'classes' => 'elementor-control-start-end',
287
+
'selectors_dictionary' => [
288
+
'left' => is_rtl() ? 'end' : 'start',
289
+
'right' => is_rtl() ? 'start' : 'end',
290
+
],
291
+
'default' => '',
292
+
'selectors' => [
293
+
'{{WRAPPER}}' => 'text-align: {{VALUE}};',
294
+
],
295
+
'separator' => 'after',
296
+
]
297
+
);
298
+
299
+
$this->add_group_control(
300
+
Group_Control_Typography::get_type(),
301
+
[
302
+
'name' => 'typography',
303
+
'global' => [
304
+
'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
305
+
],
306
+
'selector' => '{{WRAPPER}} .elementor-heading-title',
307
+
]
308
+
);
309
+
310
+
$this->add_group_control(
311
+
Group_Control_Text_Stroke::get_type(),
312
+
[
313
+
'name' => 'text_stroke',
314
+
'selector' => '{{WRAPPER}} .elementor-heading-title',
315
+
]
316
+
);
317
+
318
+
$this->add_group_control(
319
+
Group_Control_Text_Shadow::get_type(),
320
+
[
321
+
'name' => 'text_shadow',
322
+
'selector' => '{{WRAPPER}} .elementor-heading-title',
323
+
]
324
+
);
325
+
326
+
$this->add_control(
327
+
'blend_mode',
328
+
[
329
+
'label' => esc_html__( 'Blend Mode', 'elementor' ),
330
+
'type' => Controls_Manager::SELECT,
331
+
'options' => [
332
+
'' => esc_html__( 'Normal', 'elementor' ),
333
+
'multiply' => esc_html__( 'Multiply', 'elementor' ),
334
+
'screen' => esc_html__( 'Screen', 'elementor' ),
335
+
'overlay' => esc_html__( 'Overlay', 'elementor' ),
336
+
'darken' => esc_html__( 'Darken', 'elementor' ),
337
+
'lighten' => esc_html__( 'Lighten', 'elementor' ),
338
+
'color-dodge' => esc_html__( 'Color Dodge', 'elementor' ),
339
+
'saturation' => esc_html__( 'Saturation', 'elementor' ),
340
+
'color' => esc_html__( 'Color', 'elementor' ),
341
+
'difference' => esc_html__( 'Difference', 'elementor' ),
342
+
'exclusion' => esc_html__( 'Exclusion', 'elementor' ),
343
+
'hue' => esc_html__( 'Hue', 'elementor' ),
344
+
'luminosity' => esc_html__( 'Luminosity', 'elementor' ),
345
+
],
346
+
'selectors' => [
347
+
'{{WRAPPER}} .elementor-heading-title' => 'mix-blend-mode: {{VALUE}}',
348
+
],
349
+
]
350
+
);
351
+
352
+
$this->add_control(
353
+
'separator',
354
+
[
355
+
'type' => Controls_Manager::DIVIDER,
356
+
]
357
+
);
358
+
359
+
$this->start_controls_tabs( 'title_colors' );
360
+
361
+
$this->start_controls_tab(
362
+
'title_colors_normal',
363
+
[
364
+
'label' => esc_html__( 'Normal', 'elementor' ),
365
+
]
366
+
);
367
+
368
+
$this->add_control(
369
+
'title_color',
370
+
[
371
+
'label' => esc_html__( 'Text Color', 'elementor' ),
372
+
'type' => Controls_Manager::COLOR,
373
+
'global' => [
374
+
'default' => Global_Colors::COLOR_PRIMARY,
375
+
],
376
+
'selectors' => [
377
+
'{{WRAPPER}} .elementor-heading-title' => 'color: {{VALUE}};',
378
+
],
379
+
]
380
+
);
381
+
382
+
$this->end_controls_tab();
383
+
384
+
$this->start_controls_tab(
385
+
'title_colors_hover',
386
+
[
387
+
'label' => esc_html__( 'Hover', 'elementor' ),
388
+
]
389
+
);
390
+
391
+
$this->add_control(
392
+
'title_hover_color',
393
+
[
394
+
'label' => esc_html__( 'Link Color', 'elementor' ),
395
+
'type' => Controls_Manager::COLOR,
396
+
'selectors' => [
397
+
'{{WRAPPER}} .elementor-heading-title a:hover, {{WRAPPER}} .elementor-heading-title a:focus' => 'color: {{VALUE}};',
398
+
],
399
+
]
400
+
);
401
+
402
+
$this->add_control(
403
+
'title_hover_color_transition_duration',
404
+
[
405
+
'label' => esc_html__( 'Transition Duration', 'elementor' ),
406
+
'type' => Controls_Manager::SLIDER,
407
+
'size_units' => [ 's', 'ms', 'custom' ],
408
+
'default' => [
409
+
'unit' => 's',
410
+
],
411
+
'selectors' => [
412
+
'{{WRAPPER}} .elementor-heading-title a' => 'transition-duration: {{SIZE}}{{UNIT}};',
413
+
],
414
+
]
415
+
);
416
+
417
+
$this->end_controls_tab();
418
+
419
+
$this->end_controls_tabs();
420
+
421
+
$this->end_controls_section();
422
+
}
423
+
424
+
/**
425
+
* Render heading widget output on the frontend.
426
+
*
427
+
* Written in PHP and used to generate the final HTML.
428
+
*
429
+
* @since 1.0.0
430
+
* @access protected
431
+
*/
432
+
protected function render() {
433
+
$settings = $this->get_settings_for_display();
434
+
435
+
if ( '' === $settings['title'] ) {
436
+
return;
437
+
}
438
+
439
+
$this->add_render_attribute( 'title', 'class', 'elementor-heading-title' );
440
+
441
+
if ( ! empty( $settings['size'] ) ) {
442
+
$this->add_render_attribute( 'title', 'class', 'elementor-size-' . $settings['size'] );
443
+
} else {
444
+
$this->add_render_attribute( 'title', 'class', 'elementor-size-default' );
445
+
}
446
+
447
+
$this->add_inline_editing_attributes( 'title' );
448
+
449
+
$title = wp_kses_post( $settings['title'] );
450
+
451
+
if ( ! empty( $settings['link']['url'] ) ) {
452
+
$this->add_link_attributes( 'url', $settings['link'] );
453
+
454
+
$title = sprintf( '<a %1$s>%2$s</a>', $this->get_render_attribute_string( 'url' ), $title );
455
+
}
456
+
457
+
$title_html = sprintf( '<%1$s %2$s>%3$s</%1$s>', Utils::validate_html_tag( $settings['header_size'] ), $this->get_render_attribute_string( 'title' ), $title );
458
+
459
+
// PHPCS - the variable $title_html holds safe data.
460
+
echo $title_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
461
+
}
462
+
463
+
public function maybe_add_ally_heading_hint() {
464
+
$notice_id = 'ally_heading_notice';
465
+
$plugin_slug = 'pojo-accessibility';
466
+
if ( ! Hints::should_display_hint( $notice_id ) ) {
467
+
return;
468
+
}
469
+
$notice_content = esc_html__( 'Make sure your page is structured with accessibility in mind. Ally helps detect and fix common issues across your site.', 'elementor' );
470
+
471
+
$campaign_data = [
472
+
'name' => 'elementor_ea11y_campaign',
473
+
'campaign' => 'acc-scanner-plg-heading',
474
+
'source' => 'editor-heading-widget',
475
+
'medium' => 'editor',
476
+
];
477
+
478
+
$button_text = __( 'Install Plugin', 'elementor' );
479
+
$action_url = Admin_Notices::add_plg_campaign_data( Hints::get_plugin_action_url( $plugin_slug ), $campaign_data );
480
+
481
+
if ( Hints::is_plugin_installed( $plugin_slug ) && ! Hints::is_plugin_active( $plugin_slug ) ) {
482
+
$button_text = __( 'Activate Plugin', 'elementor' );
483
+
} elseif ( Hints::is_plugin_active( $plugin_slug ) && empty( get_option( 'ea11y_access_token' ) ) ) {
484
+
$button_text = __( 'Connect to Ally', 'elementor' );
485
+
$action_url = admin_url( 'admin.php?page=accessibility-settings' );
486
+
}
487
+
488
+
$this->add_control(
489
+
$notice_id,
490
+
[
491
+
'type' => Controls_Manager::RAW_HTML,
492
+
'raw' => Hints::get_notice_template( [
493
+
'display' => ! Hints::is_dismissed( $notice_id ),
494
+
'heading' => esc_html__( 'Accessible structure matters', 'elementor' ),
495
+
'type' => 'info',
496
+
'content' => $notice_content,
497
+
'icon' => true,
498
+
'dismissible' => $notice_id,
499
+
'button_text' => $button_text,
500
+
'button_event' => $notice_id,
501
+
'button_data' => [
502
+
'action_url' => $action_url,
503
+
],
504
+
], true ),
505
+
]
506
+
);
507
+
}
508
+
509
+
/**
510
+
* Render heading widget output in the editor.
511
+
*
512
+
* Written as a Backbone JavaScript template and used to generate the live preview.
513
+
*
514
+
* @since 2.9.0
515
+
* @access protected
516
+
*/
517
+
protected function content_template() {
518
+
?>
519
+
<#
520
+
let title = elementor.helpers.sanitize( settings.title, { ALLOW_DATA_ATTR: false } );
521
+
522
+
if ( '' !== settings.link?.url ) {
523
+
title = '<a href="' + elementor.helpers.sanitizeUrl( settings.link?.url ) + '">' + title + '</a>';
524
+
}
525
+
526
+
view.addRenderAttribute( 'title', 'class', [ 'elementor-heading-title' ] );
527
+
528
+
if ( '' !== settings.size ) {
529
+
view.addRenderAttribute( 'title', 'class', [ 'elementor-size-' + settings.size ] );
530
+
} else {
531
+
view.addRenderAttribute( 'title', 'class', [ 'elementor-size-default' ] );
532
+
}
533
+
534
+
view.addInlineEditingAttributes( 'title' );
535
+
536
+
var headerSizeTag = elementor.helpers.validateHTMLTag( settings.header_size ),
537
+
title_html = '<' + headerSizeTag + ' ' + view.getRenderAttributeString( 'title' ) + '>' + title + '</' + headerSizeTag + '>';
538
+
539
+
print( title_html );
540
+
#>
541
+
<?php
542
+
}
543
+
}
544
+