PluginProbe
Elementor Website Builder – more than just a page builder / 3.27.5
Elementor Website Builder – more than just a page builder v3.27.5
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 / text-editor.php

text-editor.php in Elementor Website Builder – more than just a page builder 3.27.5, at includes/widgets/text-editor.php

567 lines 12.8 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
11 /**
12 * Elementor text editor widget.
13 *
14 * Elementor widget that displays a WYSIWYG text editor, just like the WordPress
15 * editor.
16 *
17 * @since 1.0.0
18 */
19 class Widget_Text_Editor extends Widget_Base {
20
21 /**
22 * Get widget name.
23 *
24 * Retrieve text editor 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 'text-editor';
33 }
34
35 /**
36 * Get widget title.
37 *
38 * Retrieve text editor 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__( 'Text Editor', 'elementor' );
47 }
48
49 /**
50 * Get widget icon.
51 *
52 * Retrieve text editor 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-text';
61 }
62
63 /**
64 * Get widget categories.
65 *
66 * Retrieve the list of categories the text editor 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 [ 'text', 'editor' ];
91 }
92
93 /**
94 * Get style dependencies.
95 *
96 * Retrieve the list of style dependencies the widget requires.
97 *
98 * @since 3.24.0
99 * @access public
100 *
101 * @return array Widget style dependencies.
102 */
103 public function get_style_depends(): array {
104 return [ 'widget-text-editor' ];
105 }
106
107 public function has_widget_inner_wrapper(): bool {
108 return ! Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
109 }
110
111 /**
112 * Register text editor widget controls.
113 *
114 * Adds different input fields to allow the user to change and customize the widget settings.
115 *
116 * @since 3.1.0
117 * @access protected
118 */
119 protected function register_controls() {
120 $this->start_controls_section(
121 'section_editor',
122 [
123 'label' => esc_html__( 'Text Editor', 'elementor' ),
124 ]
125 );
126
127 $this->add_control(
128 'editor',
129 [
130 'label' => '',
131 'type' => Controls_Manager::WYSIWYG,
132 'default' => '<p>' . esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ) . '</p>',
133 ]
134 );
135
136 $this->add_control(
137 'drop_cap', [
138 'label' => esc_html__( 'Drop Cap', 'elementor' ),
139 'type' => Controls_Manager::SWITCHER,
140 'label_off' => esc_html__( 'Off', 'elementor' ),
141 'label_on' => esc_html__( 'On', 'elementor' ),
142 'prefix_class' => 'elementor-drop-cap-',
143 'frontend_available' => true,
144 ]
145 );
146
147 $this->add_responsive_control(
148 'text_columns',
149 [
150 'label' => esc_html__( 'Columns', 'elementor' ),
151 'type' => Controls_Manager::SELECT,
152 'separator' => 'before',
153 'options' => [
154 '' => esc_html__( 'Default', 'elementor' ),
155 '1' => esc_html__( '1', 'elementor' ),
156 '2' => esc_html__( '2', 'elementor' ),
157 '3' => esc_html__( '3', 'elementor' ),
158 '4' => esc_html__( '4', 'elementor' ),
159 '5' => esc_html__( '5', 'elementor' ),
160 '6' => esc_html__( '6', 'elementor' ),
161 '7' => esc_html__( '7', 'elementor' ),
162 '8' => esc_html__( '8', 'elementor' ),
163 '9' => esc_html__( '9', 'elementor' ),
164 '10' => esc_html__( '10', 'elementor' ),
165 ],
166 'selectors' => [
167 '{{WRAPPER}}' => 'columns: {{VALUE}};',
168 ],
169 ]
170 );
171
172 $this->add_responsive_control(
173 'column_gap',
174 [
175 'label' => esc_html__( 'Columns Gap', 'elementor' ),
176 'type' => Controls_Manager::SLIDER,
177 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
178 'range' => [
179 'px' => [
180 'max' => 100,
181 ],
182 '%' => [
183 'max' => 10,
184 'step' => 0.1,
185 ],
186 'vw' => [
187 'max' => 10,
188 'step' => 0.1,
189 ],
190 'em' => [
191 'max' => 10,
192 ],
193 'rem' => [
194 'max' => 10,
195 ],
196 ],
197 'selectors' => [
198 '{{WRAPPER}}' => 'column-gap: {{SIZE}}{{UNIT}};',
199 ],
200 'conditions' => [
201 'relation' => 'or',
202 'terms' => [
203 [
204 'name' => 'text_columns',
205 'operator' => '>',
206 'value' => 1,
207 ],
208 [
209 'name' => 'text_columns',
210 'operator' => '===',
211 'value' => '',
212 ],
213 ],
214 ],
215 ]
216 );
217
218 $this->end_controls_section();
219
220 $this->start_controls_section(
221 'section_style',
222 [
223 'label' => esc_html__( 'Text Editor', 'elementor' ),
224 'tab' => Controls_Manager::TAB_STYLE,
225 ]
226 );
227
228 $this->add_responsive_control(
229 'align',
230 [
231 'label' => esc_html__( 'Alignment', 'elementor' ),
232 'type' => Controls_Manager::CHOOSE,
233 'options' => [
234 'left' => [
235 'title' => esc_html__( 'Left', 'elementor' ),
236 'icon' => 'eicon-text-align-left',
237 ],
238 'center' => [
239 'title' => esc_html__( 'Center', 'elementor' ),
240 'icon' => 'eicon-text-align-center',
241 ],
242 'right' => [
243 'title' => esc_html__( 'Right', 'elementor' ),
244 'icon' => 'eicon-text-align-right',
245 ],
246 'justify' => [
247 'title' => esc_html__( 'Justified', 'elementor' ),
248 'icon' => 'eicon-text-align-justify',
249 ],
250 ],
251 'selectors' => [
252 '{{WRAPPER}}' => 'text-align: {{VALUE}};',
253 ],
254 ]
255 );
256
257 $this->add_control(
258 'text_color',
259 [
260 'label' => esc_html__( 'Text Color', 'elementor' ),
261 'type' => Controls_Manager::COLOR,
262 'default' => '',
263 'selectors' => [
264 '{{WRAPPER}}' => 'color: {{VALUE}};',
265 ],
266 'global' => [
267 'default' => Global_Colors::COLOR_TEXT,
268 ],
269 ]
270 );
271
272 $this->add_group_control(
273 Group_Control_Typography::get_type(),
274 [
275 'name' => 'typography',
276 'global' => [
277 'default' => Global_Typography::TYPOGRAPHY_TEXT,
278 ],
279 ]
280 );
281
282 $this->add_group_control(
283 Group_Control_Text_Shadow::get_type(),
284 [
285 'name' => 'text_shadow',
286 'selector' => '{{WRAPPER}}',
287 ]
288 );
289
290 $this->add_responsive_control(
291 'paragraph_spacing',
292 [
293 'label' => esc_html__( 'Paragraph Spacing', 'elementor' ),
294 'type' => Controls_Manager::SLIDER,
295 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ],
296 'range' => [
297 'px' => [
298 'max' => 100,
299 ],
300 'em' => [
301 'min' => 0.1,
302 'max' => 20,
303 ],
304 ],
305 'selectors' => [
306 '{{WRAPPER}} p' => 'margin-bottom: {{SIZE}}{{UNIT}}',
307 ],
308 ]
309 );
310
311 $this->end_controls_section();
312
313 $this->start_controls_section(
314 'section_drop_cap',
315 [
316 'label' => esc_html__( 'Drop Cap', 'elementor' ),
317 'tab' => Controls_Manager::TAB_STYLE,
318 'condition' => [
319 'drop_cap' => 'yes',
320 ],
321 ]
322 );
323
324 $this->add_control(
325 'drop_cap_view',
326 [
327 'label' => esc_html__( 'View', 'elementor' ),
328 'type' => Controls_Manager::SELECT,
329 'options' => [
330 'default' => esc_html__( 'Default', 'elementor' ),
331 'stacked' => esc_html__( 'Stacked', 'elementor' ),
332 'framed' => esc_html__( 'Framed', 'elementor' ),
333 ],
334 'default' => 'default',
335 'prefix_class' => 'elementor-drop-cap-view-',
336 ]
337 );
338
339 $this->add_control(
340 'drop_cap_primary_color',
341 [
342 'label' => esc_html__( 'Primary Color', 'elementor' ),
343 'type' => Controls_Manager::COLOR,
344 'selectors' => [
345 '{{WRAPPER}}.elementor-drop-cap-view-stacked .elementor-drop-cap' => 'background-color: {{VALUE}};',
346 '{{WRAPPER}}.elementor-drop-cap-view-framed .elementor-drop-cap, {{WRAPPER}}.elementor-drop-cap-view-default .elementor-drop-cap' => 'color: {{VALUE}}; border-color: {{VALUE}};',
347 ],
348 'global' => [
349 'default' => Global_Colors::COLOR_PRIMARY,
350 ],
351 ]
352 );
353
354 $this->add_control(
355 'drop_cap_secondary_color',
356 [
357 'label' => esc_html__( 'Secondary Color', 'elementor' ),
358 'type' => Controls_Manager::COLOR,
359 'selectors' => [
360 '{{WRAPPER}}.elementor-drop-cap-view-framed .elementor-drop-cap' => 'background-color: {{VALUE}};',
361 '{{WRAPPER}}.elementor-drop-cap-view-stacked .elementor-drop-cap' => 'color: {{VALUE}};',
362 ],
363 'condition' => [
364 'drop_cap_view!' => 'default',
365 ],
366 ]
367 );
368
369 $this->add_group_control(
370 Group_Control_Text_Shadow::get_type(),
371 [
372 'name' => 'drop_cap_shadow',
373 'selector' => '{{WRAPPER}} .elementor-drop-cap',
374 ]
375 );
376
377 $this->add_control(
378 'drop_cap_size',
379 [
380 'label' => esc_html__( 'Size', 'elementor' ),
381 'type' => Controls_Manager::SLIDER,
382 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
383 'default' => [
384 'size' => 5,
385 ],
386 'range' => [
387 'px' => [
388 'max' => 30,
389 ],
390 'em' => [
391 'max' => 3,
392 ],
393 'rem' => [
394 'max' => 3,
395 ],
396 ],
397 'selectors' => [
398 '{{WRAPPER}} .elementor-drop-cap' => 'padding: {{SIZE}}{{UNIT}};',
399 ],
400 'condition' => [
401 'drop_cap_view!' => 'default',
402 ],
403 ]
404 );
405
406 $this->add_control(
407 'drop_cap_space',
408 [
409 'label' => esc_html__( 'Space', 'elementor' ),
410 'type' => Controls_Manager::SLIDER,
411 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
412 'default' => [
413 'size' => 10,
414 ],
415 'range' => [
416 'px' => [
417 'max' => 50,
418 ],
419 'em' => [
420 'max' => 5,
421 ],
422 'rem' => [
423 'max' => 5,
424 ],
425 ],
426 'selectors' => [
427 'body:not(.rtl) {{WRAPPER}} .elementor-drop-cap' => 'margin-right: {{SIZE}}{{UNIT}};',
428 'body.rtl {{WRAPPER}} .elementor-drop-cap' => 'margin-left: {{SIZE}}{{UNIT}};',
429 ],
430 ]
431 );
432
433 $this->add_control(
434 'drop_cap_border_radius',
435 [
436 'label' => esc_html__( 'Border Radius', 'elementor' ),
437 'type' => Controls_Manager::SLIDER,
438 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
439 'default' => [
440 'unit' => '%',
441 ],
442 'range' => [
443 '%' => [
444 'max' => 50,
445 ],
446 ],
447 'selectors' => [
448 '{{WRAPPER}} .elementor-drop-cap' => 'border-radius: {{SIZE}}{{UNIT}};',
449 ],
450 'condition' => [
451 'drop_cap_view!' => 'default',
452 ],
453 ]
454 );
455
456 $this->add_control(
457 'drop_cap_border_width', [
458 'label' => esc_html__( 'Border Width', 'elementor' ),
459 'type' => Controls_Manager::DIMENSIONS,
460 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
461 'selectors' => [
462 '{{WRAPPER}} .elementor-drop-cap' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
463 ],
464 'condition' => [
465 'drop_cap_view' => 'framed',
466 ],
467 ]
468 );
469
470 $this->add_group_control(
471 Group_Control_Typography::get_type(),
472 [
473 'name' => 'drop_cap_typography',
474 'selector' => '{{WRAPPER}} .elementor-drop-cap-letter',
475 'exclude' => [
476 'letter_spacing',
477 ],
478 ]
479 );
480
481 $this->end_controls_section();
482 }
483
484 /**
485 * Render text editor widget output on the frontend.
486 *
487 * Written in PHP and used to generate the final HTML.
488 *
489 * @since 1.0.0
490 * @access protected
491 */
492 protected function render() {
493 $should_render_inline_editing = Plugin::$instance->editor->is_edit_mode();
494
495 $editor_content = $this->get_settings_for_display( 'editor' );
496 $editor_content = $this->parse_text_editor( $editor_content );
497
498 if ( empty( $editor_content ) ) {
499 return;
500 }
501
502 if ( $should_render_inline_editing ) {
503 $this->add_render_attribute( 'editor', 'class', [ 'elementor-text-editor', 'elementor-clearfix' ] );
504 }
505
506 $this->add_inline_editing_attributes( 'editor', 'advanced' );
507 ?>
508 <?php if ( $should_render_inline_editing ) { ?>
509 <div <?php $this->print_render_attribute_string( 'editor' ); ?>>
510 <?php } ?>
511 <?php // PHPCS - the main text of a widget should not be escaped.
512 echo $editor_content; // phpcs:ignore WordPress.Security.EscapeOutput ?>
513 <?php if ( $should_render_inline_editing ) { ?>
514 </div>
515 <?php } ?>
516 <?php
517 }
518
519 /**
520 * Render text editor widget as plain content.
521 *
522 * Override the default behavior by printing the content without rendering it.
523 *
524 * @since 1.0.0
525 * @access public
526 */
527 public function render_plain_content() {
528 // In plain mode, render without shortcode
529 $this->print_unescaped_setting( 'editor' );
530 }
531
532 /**
533 * Render text editor widget output in the editor.
534 *
535 * Written as a Backbone JavaScript template and used to generate the live preview.
536 *
537 * @since 2.9.0
538 * @access protected
539 */
540 protected function content_template() {
541 ?>
542 <#
543 if ( '' === settings.editor ) {
544 return;
545 }
546
547 const shouldRenderInlineEditing = elementorFrontend.isEditMode();
548
549 if ( shouldRenderInlineEditing ) {
550 view.addRenderAttribute( 'editor', 'class', [ 'elementor-text-editor', 'elementor-clearfix' ] );
551 }
552
553 view.addInlineEditingAttributes( 'editor', 'advanced' );
554
555 if ( shouldRenderInlineEditing ) { #>
556 <div {{{ view.getRenderAttributeString( 'editor' ) }}}>
557 <# } #>
558
559 {{{ settings.editor }}}
560
561 <# if ( shouldRenderInlineEditing ) { #>
562 </div>
563 <# } #>
564 <?php
565 }
566 }
567