PluginProbe
Elementor Website Builder – more than just a page builder / 3.22.0-dev4
Elementor Website Builder – more than just a page builder v3.22.0-dev4
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 / includes / widgets / heading.php

heading.php in Elementor Website Builder – more than just a page builder 3.22.0-dev4, at includes/widgets/heading.php

414 lines 10.0 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 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
12 /**
13 * Elementor heading widget.
14 *
15 * Elementor widget that displays an eye-catching headlines.
16 *
17 * @since 1.0.0
18 */
19 class Widget_Heading extends Widget_Base implements Sanitizable {
20
21 /**
22 * Get widget name.
23 *
24 * Retrieve heading widget name.
25 *
26 * @since 1.0.0
27 * @access public
28 *
29 * @return string Widget name.
30 */
31 public function get_name() {
32 return 'heading';
33 }
34
35 /**
36 * Get widget title.
37 *
38 * Retrieve heading widget title.
39 *
40 * @since 1.0.0
41 * @access public
42 *
43 * @return string Widget title.
44 */
45 public function get_title() {
46 return esc_html__( 'Heading', 'elementor' );
47 }
48
49 /**
50 * Get widget icon.
51 *
52 * Retrieve heading widget icon.
53 *
54 * @since 1.0.0
55 * @access public
56 *
57 * @return string Widget icon.
58 */
59 public function get_icon() {
60 return 'eicon-t-letter';
61 }
62
63 /**
64 * Get widget categories.
65 *
66 * Retrieve the list of categories the heading widget belongs to.
67 *
68 * Used to determine where to display the widget in the editor.
69 *
70 * @since 2.0.0
71 * @access public
72 *
73 * @return array Widget categories.
74 */
75 public function get_categories() {
76 return [ 'basic' ];
77 }
78
79 /**
80 * Get widget keywords.
81 *
82 * Retrieve the list of keywords the widget belongs to.
83 *
84 * @since 2.1.0
85 * @access public
86 *
87 * @return array Widget keywords.
88 */
89 public function get_keywords() {
90 return [ 'heading', 'title', 'text' ];
91 }
92
93 protected function is_dynamic_content(): bool {
94 return false;
95 }
96
97 /**
98 * Remove data attributes from the html.
99 *
100 * @param string $content Heading title
101 * @return string
102 */
103 public function sanitize( $content ): string {
104 $allowed_tags = wp_kses_allowed_html( 'post' );
105 $allowed_tags_for_heading = [];
106 $non_allowed_tags = [ 'img' ];
107
108 foreach ( $allowed_tags as $tag => $attributes ) {
109 if ( in_array( $tag, $non_allowed_tags, true ) ) {
110 continue;
111 }
112
113 $filtered_attributes = array_filter( $attributes, function( $attribute ) {
114 return ! str_starts_with( $attribute, 'data-' );
115 }, ARRAY_FILTER_USE_KEY );
116
117 $allowed_tags_for_heading[ $tag ] = $filtered_attributes;
118 }
119
120 return wp_kses( $content, $allowed_tags_for_heading );
121 }
122
123 /**
124 * Get widget upsale data.
125 *
126 * Retrieve the widget promotion data.
127 *
128 * @since 3.18.0
129 * @access protected
130 *
131 * @return array Widget promotion data.
132 */
133 protected function get_upsale_data() {
134 return [
135 'condition' => ! Utils::has_pro(),
136 'image' => esc_url( ELEMENTOR_ASSETS_URL . 'images/go-pro.svg' ),
137 'image_alt' => esc_attr__( 'Upgrade', 'elementor' ),
138 'description' => esc_html__( 'Create captivating headings that rotate with the Animated Headline Widget.', 'elementor' ),
139 'upgrade_url' => esc_url( 'https://go.elementor.com/go-pro-heading-widget/' ),
140 'upgrade_text' => esc_html__( 'Upgrade Now', 'elementor' ),
141 ];
142 }
143
144 /**
145 * Register heading widget controls.
146 *
147 * Adds different input fields to allow the user to change and customize the widget settings.
148 *
149 * @since 3.1.0
150 * @access protected
151 */
152 protected function register_controls() {
153 $this->start_controls_section(
154 'section_title',
155 [
156 'label' => esc_html__( 'Heading', 'elementor' ),
157 ]
158 );
159
160 $this->add_control(
161 'title',
162 [
163 'label' => esc_html__( 'Title', 'elementor' ),
164 'type' => Controls_Manager::TEXTAREA,
165 'ai' => [
166 'type' => 'text',
167 ],
168 'dynamic' => [
169 'active' => true,
170 ],
171 'placeholder' => esc_html__( 'Enter your title', 'elementor' ),
172 'default' => esc_html__( 'Add Your Heading Text Here', 'elementor' ),
173 ]
174 );
175
176 $this->add_control(
177 'link',
178 [
179 'label' => esc_html__( 'Link', 'elementor' ),
180 'type' => Controls_Manager::URL,
181 'dynamic' => [
182 'active' => true,
183 ],
184 'default' => [
185 'url' => '',
186 ],
187 ]
188 );
189
190 $this->add_control(
191 'size',
192 [
193 'label' => esc_html__( 'Size', 'elementor' ),
194 'type' => Controls_Manager::SELECT,
195 'options' => [
196 'default' => esc_html__( 'Default', 'elementor' ),
197 'small' => esc_html__( 'Small', 'elementor' ),
198 'medium' => esc_html__( 'Medium', 'elementor' ),
199 'large' => esc_html__( 'Large', 'elementor' ),
200 'xl' => esc_html__( 'XL', 'elementor' ),
201 'xxl' => esc_html__( 'XXL', 'elementor' ),
202 ],
203 'default' => 'default',
204 'condition' => [
205 'size!' => 'default', // a workaround to hide the control, unless it's in use (not default).
206 ],
207 ]
208 );
209
210 $this->add_control(
211 'header_size',
212 [
213 'label' => esc_html__( 'HTML Tag', 'elementor' ),
214 'type' => Controls_Manager::SELECT,
215 'options' => [
216 'h1' => 'H1',
217 'h2' => 'H2',
218 'h3' => 'H3',
219 'h4' => 'H4',
220 'h5' => 'H5',
221 'h6' => 'H6',
222 'div' => 'div',
223 'span' => 'span',
224 'p' => 'p',
225 ],
226 'default' => 'h2',
227 ]
228 );
229
230 $this->end_controls_section();
231
232 $this->start_controls_section(
233 'section_title_style',
234 [
235 'label' => esc_html__( 'Heading', 'elementor' ),
236 'tab' => Controls_Manager::TAB_STYLE,
237 ]
238 );
239
240 $this->add_responsive_control(
241 'align',
242 [
243 'label' => esc_html__( 'Alignment', 'elementor' ),
244 'type' => Controls_Manager::CHOOSE,
245 'options' => [
246 'left' => [
247 'title' => esc_html__( 'Left', 'elementor' ),
248 'icon' => 'eicon-text-align-left',
249 ],
250 'center' => [
251 'title' => esc_html__( 'Center', 'elementor' ),
252 'icon' => 'eicon-text-align-center',
253 ],
254 'right' => [
255 'title' => esc_html__( 'Right', 'elementor' ),
256 'icon' => 'eicon-text-align-right',
257 ],
258 'justify' => [
259 'title' => esc_html__( 'Justified', 'elementor' ),
260 'icon' => 'eicon-text-align-justify',
261 ],
262 ],
263 'default' => '',
264 'selectors' => [
265 '{{WRAPPER}}' => 'text-align: {{VALUE}};',
266 ],
267 ]
268 );
269
270 $this->add_control(
271 'title_color',
272 [
273 'label' => esc_html__( 'Text Color', 'elementor' ),
274 'type' => Controls_Manager::COLOR,
275 'global' => [
276 'default' => Global_Colors::COLOR_PRIMARY,
277 ],
278 'selectors' => [
279 '{{WRAPPER}} .elementor-heading-title' => 'color: {{VALUE}};',
280 ],
281 ]
282 );
283
284 $this->add_group_control(
285 Group_Control_Typography::get_type(),
286 [
287 'name' => 'typography',
288 'global' => [
289 'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
290 ],
291 'selector' => '{{WRAPPER}} .elementor-heading-title',
292 ]
293 );
294
295 $this->add_group_control(
296 Group_Control_Text_Stroke::get_type(),
297 [
298 'name' => 'text_stroke',
299 'selector' => '{{WRAPPER}} .elementor-heading-title',
300 ]
301 );
302
303 $this->add_group_control(
304 Group_Control_Text_Shadow::get_type(),
305 [
306 'name' => 'text_shadow',
307 'selector' => '{{WRAPPER}} .elementor-heading-title',
308 ]
309 );
310
311 $this->add_control(
312 'blend_mode',
313 [
314 'label' => esc_html__( 'Blend Mode', 'elementor' ),
315 'type' => Controls_Manager::SELECT,
316 'options' => [
317 '' => esc_html__( 'Normal', 'elementor' ),
318 'multiply' => esc_html__( 'Multiply', 'elementor' ),
319 'screen' => esc_html__( 'Screen', 'elementor' ),
320 'overlay' => esc_html__( 'Overlay', 'elementor' ),
321 'darken' => esc_html__( 'Darken', 'elementor' ),
322 'lighten' => esc_html__( 'Lighten', 'elementor' ),
323 'color-dodge' => esc_html__( 'Color Dodge', 'elementor' ),
324 'saturation' => esc_html__( 'Saturation', 'elementor' ),
325 'color' => esc_html__( 'Color', 'elementor' ),
326 'difference' => esc_html__( 'Difference', 'elementor' ),
327 'exclusion' => esc_html__( 'Exclusion', 'elementor' ),
328 'hue' => esc_html__( 'Hue', 'elementor' ),
329 'luminosity' => esc_html__( 'Luminosity', 'elementor' ),
330 ],
331 'selectors' => [
332 '{{WRAPPER}} .elementor-heading-title' => 'mix-blend-mode: {{VALUE}}',
333 ],
334 ]
335 );
336
337 $this->end_controls_section();
338 }
339
340 /**
341 * Render heading widget output on the frontend.
342 *
343 * Written in PHP and used to generate the final HTML.
344 *
345 * @since 1.0.0
346 * @access protected
347 */
348 protected function render() {
349 $settings = $this->get_settings_for_display();
350
351 if ( '' === $settings['title'] ) {
352 return;
353 }
354
355 $this->add_render_attribute( 'title', 'class', 'elementor-heading-title' );
356
357 if ( ! empty( $settings['size'] ) ) {
358 $this->add_render_attribute( 'title', 'class', 'elementor-size-' . $settings['size'] );
359 } else {
360 $this->add_render_attribute( 'title', 'class', 'elementor-size-default' );
361 }
362
363 $this->add_inline_editing_attributes( 'title' );
364
365 $title = $settings['title'];
366
367 if ( ! empty( $settings['link']['url'] ) ) {
368 $this->add_link_attributes( 'url', $settings['link'] );
369
370 $title = sprintf( '<a %1$s>%2$s</a>', $this->get_render_attribute_string( 'url' ), $title );
371 }
372
373 $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 );
374
375 // PHPCS - the variable $title_html holds safe data.
376 echo $title_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
377 }
378
379 /**
380 * Render heading widget output in the editor.
381 *
382 * Written as a Backbone JavaScript template and used to generate the live preview.
383 *
384 * @since 2.9.0
385 * @access protected
386 */
387 protected function content_template() {
388 ?>
389 <#
390 let title = elementor.helpers.sanitize( settings.title, { ALLOW_DATA_ATTR: false } );
391
392 if ( '' !== settings.link.url ) {
393 title = '<a href="' + _.escape( settings.link.url ) + '">' + title + '</a>';
394 }
395
396 view.addRenderAttribute( 'title', 'class', [ 'elementor-heading-title' ] );
397
398 if ( '' !== settings.size ) {
399 view.addRenderAttribute( 'title', 'class', [ 'elementor-size-' + settings.size ] );
400 } else {
401 view.addRenderAttribute( 'title', 'class', [ 'elementor-size-default' ] );
402 }
403
404 view.addInlineEditingAttributes( 'title' );
405
406 var headerSizeTag = elementor.helpers.validateHTMLTag( settings.header_size ),
407 title_html = '<' + headerSizeTag + ' ' + view.getRenderAttributeString( 'title' ) + '>' + title + '</' + headerSizeTag + '>';
408
409 print( title_html );
410 #>
411 <?php
412 }
413 }
414