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

546 lines 12.3 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 /**
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->end_controls_section();
291
292 $this->start_controls_section(
293 'section_drop_cap',
294 [
295 'label' => esc_html__( 'Drop Cap', 'elementor' ),
296 'tab' => Controls_Manager::TAB_STYLE,
297 'condition' => [
298 'drop_cap' => 'yes',
299 ],
300 ]
301 );
302
303 $this->add_control(
304 'drop_cap_view',
305 [
306 'label' => esc_html__( 'View', 'elementor' ),
307 'type' => Controls_Manager::SELECT,
308 'options' => [
309 'default' => esc_html__( 'Default', 'elementor' ),
310 'stacked' => esc_html__( 'Stacked', 'elementor' ),
311 'framed' => esc_html__( 'Framed', 'elementor' ),
312 ],
313 'default' => 'default',
314 'prefix_class' => 'elementor-drop-cap-view-',
315 ]
316 );
317
318 $this->add_control(
319 'drop_cap_primary_color',
320 [
321 'label' => esc_html__( 'Primary Color', 'elementor' ),
322 'type' => Controls_Manager::COLOR,
323 'selectors' => [
324 '{{WRAPPER}}.elementor-drop-cap-view-stacked .elementor-drop-cap' => 'background-color: {{VALUE}};',
325 '{{WRAPPER}}.elementor-drop-cap-view-framed .elementor-drop-cap, {{WRAPPER}}.elementor-drop-cap-view-default .elementor-drop-cap' => 'color: {{VALUE}}; border-color: {{VALUE}};',
326 ],
327 'global' => [
328 'default' => Global_Colors::COLOR_PRIMARY,
329 ],
330 ]
331 );
332
333 $this->add_control(
334 'drop_cap_secondary_color',
335 [
336 'label' => esc_html__( 'Secondary Color', 'elementor' ),
337 'type' => Controls_Manager::COLOR,
338 'selectors' => [
339 '{{WRAPPER}}.elementor-drop-cap-view-framed .elementor-drop-cap' => 'background-color: {{VALUE}};',
340 '{{WRAPPER}}.elementor-drop-cap-view-stacked .elementor-drop-cap' => 'color: {{VALUE}};',
341 ],
342 'condition' => [
343 'drop_cap_view!' => 'default',
344 ],
345 ]
346 );
347
348 $this->add_group_control(
349 Group_Control_Text_Shadow::get_type(),
350 [
351 'name' => 'drop_cap_shadow',
352 'selector' => '{{WRAPPER}} .elementor-drop-cap',
353 ]
354 );
355
356 $this->add_control(
357 'drop_cap_size',
358 [
359 'label' => esc_html__( 'Size', 'elementor' ),
360 'type' => Controls_Manager::SLIDER,
361 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
362 'default' => [
363 'size' => 5,
364 ],
365 'range' => [
366 'px' => [
367 'max' => 30,
368 ],
369 'em' => [
370 'max' => 3,
371 ],
372 'rem' => [
373 'max' => 3,
374 ],
375 ],
376 'selectors' => [
377 '{{WRAPPER}} .elementor-drop-cap' => 'padding: {{SIZE}}{{UNIT}};',
378 ],
379 'condition' => [
380 'drop_cap_view!' => 'default',
381 ],
382 ]
383 );
384
385 $this->add_control(
386 'drop_cap_space',
387 [
388 'label' => esc_html__( 'Space', 'elementor' ),
389 'type' => Controls_Manager::SLIDER,
390 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
391 'default' => [
392 'size' => 10,
393 ],
394 'range' => [
395 'px' => [
396 'max' => 50,
397 ],
398 'em' => [
399 'max' => 5,
400 ],
401 'rem' => [
402 'max' => 5,
403 ],
404 ],
405 'selectors' => [
406 'body:not(.rtl) {{WRAPPER}} .elementor-drop-cap' => 'margin-right: {{SIZE}}{{UNIT}};',
407 'body.rtl {{WRAPPER}} .elementor-drop-cap' => 'margin-left: {{SIZE}}{{UNIT}};',
408 ],
409 ]
410 );
411
412 $this->add_control(
413 'drop_cap_border_radius',
414 [
415 'label' => esc_html__( 'Border Radius', 'elementor' ),
416 'type' => Controls_Manager::SLIDER,
417 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
418 'default' => [
419 'unit' => '%',
420 ],
421 'range' => [
422 '%' => [
423 'max' => 50,
424 ],
425 ],
426 'selectors' => [
427 '{{WRAPPER}} .elementor-drop-cap' => 'border-radius: {{SIZE}}{{UNIT}};',
428 ],
429 'condition' => [
430 'drop_cap_view!' => 'default',
431 ],
432 ]
433 );
434
435 $this->add_control(
436 'drop_cap_border_width', [
437 'label' => esc_html__( 'Border Width', 'elementor' ),
438 'type' => Controls_Manager::DIMENSIONS,
439 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
440 'selectors' => [
441 '{{WRAPPER}} .elementor-drop-cap' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
442 ],
443 'condition' => [
444 'drop_cap_view' => 'framed',
445 ],
446 ]
447 );
448
449 $this->add_group_control(
450 Group_Control_Typography::get_type(),
451 [
452 'name' => 'drop_cap_typography',
453 'selector' => '{{WRAPPER}} .elementor-drop-cap-letter',
454 'exclude' => [
455 'letter_spacing',
456 ],
457 ]
458 );
459
460 $this->end_controls_section();
461 }
462
463 /**
464 * Render text editor widget output on the frontend.
465 *
466 * Written in PHP and used to generate the final HTML.
467 *
468 * @since 1.0.0
469 * @access protected
470 */
471 protected function render() {
472 $should_render_inline_editing = Plugin::$instance->editor->is_edit_mode();
473
474 $editor_content = $this->get_settings_for_display( 'editor' );
475 $editor_content = $this->parse_text_editor( $editor_content );
476
477 if ( empty( $editor_content ) ) {
478 return;
479 }
480
481 if ( $should_render_inline_editing ) {
482 $this->add_render_attribute( 'editor', 'class', [ 'elementor-text-editor', 'elementor-clearfix' ] );
483 }
484
485 $this->add_inline_editing_attributes( 'editor', 'advanced' );
486 ?>
487 <?php if ( $should_render_inline_editing ) { ?>
488 <div <?php $this->print_render_attribute_string( 'editor' ); ?>>
489 <?php } ?>
490 <?php // PHPCS - the main text of a widget should not be escaped.
491 echo $editor_content; // phpcs:ignore WordPress.Security.EscapeOutput ?>
492 <?php if ( $should_render_inline_editing ) { ?>
493 </div>
494 <?php } ?>
495 <?php
496 }
497
498 /**
499 * Render text editor widget as plain content.
500 *
501 * Override the default behavior by printing the content without rendering it.
502 *
503 * @since 1.0.0
504 * @access public
505 */
506 public function render_plain_content() {
507 // In plain mode, render without shortcode
508 $this->print_unescaped_setting( 'editor' );
509 }
510
511 /**
512 * Render text editor widget output in the editor.
513 *
514 * Written as a Backbone JavaScript template and used to generate the live preview.
515 *
516 * @since 2.9.0
517 * @access protected
518 */
519 protected function content_template() {
520 ?>
521 <#
522 if ( '' === settings.editor ) {
523 return;
524 }
525
526 const shouldRenderInlineEditing = elementorFrontend.isEditMode();
527
528 if ( shouldRenderInlineEditing ) {
529 view.addRenderAttribute( 'editor', 'class', [ 'elementor-text-editor', 'elementor-clearfix' ] );
530 }
531
532 view.addInlineEditingAttributes( 'editor', 'advanced' );
533
534 if ( shouldRenderInlineEditing ) { #>
535 <div {{{ view.getRenderAttributeString( 'editor' ) }}}>
536 <# } #>
537
538 {{{ settings.editor }}}
539
540 <# if ( shouldRenderInlineEditing ) { #>
541 </div>
542 <# } #>
543 <?php
544 }
545 }
546