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

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