PluginProbe
Elementor Website Builder – more than just a page builder / 3.26.0-dev5
Elementor Website Builder – more than just a page builder v3.26.0-dev5
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.26.0-dev5, at includes/widgets/text-editor.php

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