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

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