PluginProbe
Elementor Website Builder – more than just a page builder / 4.2.4
Elementor Website Builder – more than just a page builder v4.2.4
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 / preview.php

preview.php in Elementor Website Builder – more than just a page builder 4.2.4, at includes/preview.php

378 lines 8.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 use Elementor\Core\Base\App;
5 use Elementor\Core\Editor\Editor;
6 use Elementor\Core\Settings\Manager as SettingsManager;
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit; // Exit if accessed directly.
10 }
11
12 /**
13 * Elementor preview.
14 *
15 * Elementor preview handler class is responsible for initializing Elementor in
16 * preview mode.
17 *
18 * @since 1.0.0
19 */
20 class Preview extends App {
21
22 /**
23 * The priority of the preview enqueued styles.
24 */
25 const ENQUEUED_STYLES_PRIORITY = 20;
26
27 /**
28 * Is Preview.
29 *
30 * Holds a flag if current request is a preview.
31 * The flag is not related to a specific post or edit permissions.
32 *
33 * @since 2.9.5
34 * @access private
35 *
36 * @var bool Is Preview.
37 */
38
39 private $is_preview;
40
41 /**
42 * Post ID.
43 *
44 * Holds the ID of the current post being previewed.
45 *
46 * @since 1.0.0
47 * @access private
48 *
49 * @var int Post ID.
50 */
51 private $post_id;
52
53 /**
54 * Get module name.
55 *
56 * Retrieve the module name.
57 *
58 * @since 3.0.0
59 * @access public
60 * @abstract
61 *
62 * @return string Module name.
63 */
64 public function get_name() {
65 return 'preview';
66 }
67
68 /**
69 * Init.
70 *
71 * Initialize Elementor preview mode.
72 *
73 * Fired by `template_redirect` action.
74 *
75 * @since 1.0.0
76 * @access public
77 */
78 public function init() {
79 if ( is_admin() || ! $this->is_preview_mode() ) {
80 return;
81 }
82
83 if ( isset( $_GET['preview-debug'] ) ) {
84 register_shutdown_function( function () {
85 $e = error_get_last();
86 if ( $e ) {
87 echo '<div id="elementor-preview-debug-error"><pre>';
88 Utils::print_unescaped_internal_string( $e['message'] );
89 echo '</pre></div>';
90 }
91 } );
92 }
93
94 $this->post_id = get_the_ID();
95 $this->is_preview = true;
96
97 // Send Document-Isolation-Policy on the preview iframe so it shares
98 // an agent cluster with the editor parent and synchronous DOM access
99 // (e.g. iframe.contentWindow.elementorFrontend) keeps working.
100 Editor::send_document_isolation_policy_header();
101
102 // Don't redirect to permalink.
103 remove_action( 'template_redirect', 'redirect_canonical' );
104
105 // Compatibility with Yoast SEO plugin when 'Removes unneeded query variables from the URL' enabled.
106 // TODO: Move this code to `includes/compatibility.php`.
107 if ( class_exists( 'WPSEO_Frontend' ) ) {
108 remove_action( 'template_redirect', [ \WPSEO_Frontend::get_instance(), 'clean_permalink' ], 1 );
109 }
110
111 // Disable the WP admin bar in preview mode.
112 add_filter( 'show_admin_bar', '__return_false' );
113
114 add_action( 'wp_enqueue_scripts', function() {
115 $this->enqueue_styles();
116 $this->enqueue_scripts();
117 }, self::ENQUEUED_STYLES_PRIORITY );
118
119 add_filter( 'the_content', [ $this, 'builder_wrapper' ], 999999 );
120
121 add_action( 'wp_footer', [ $this, 'wp_footer' ] );
122
123 // Avoid Cloudflare's Rocket Loader lazy load the editor iframe
124 add_filter( 'script_loader_tag', [ $this, 'rocket_loader_filter' ], 10, 3 );
125
126 // Tell to WP Cache plugins do not cache this request.
127 Utils::do_not_cache();
128
129 /**
130 * Preview init.
131 *
132 * Fires on Elementor preview init, after Elementor preview has finished
133 * loading but before any headers are sent.
134 *
135 * @since 1.0.0
136 *
137 * @param Preview $this The current preview.
138 */
139 do_action( 'elementor/preview/init', $this );
140 }
141
142 /**
143 * Retrieve post ID.
144 *
145 * Get the ID of the current post.
146 *
147 * @since 1.8.0
148 * @access public
149 *
150 * @return int Post ID.
151 */
152 public function get_post_id() {
153 return $this->post_id;
154 }
155
156 /**
157 * Is Preview.
158 *
159 * Whether current request is the elementor preview iframe.
160 * The flag is not related to a specific post or edit permissions.
161 *
162 * @since 2.9.5
163 * @access public
164 *
165 * @return bool
166 */
167 public function is_preview() {
168 return $this->is_preview;
169 }
170
171 /**
172 * Whether preview mode is active.
173 *
174 * Used to determine whether we are in the preview mode (iframe).
175 *
176 * @since 1.0.0
177 * @access public
178 *
179 * @param int $post_id Optional. Post ID. Default is `0`.
180 *
181 * @return bool Whether preview mode is active.
182 */
183 public function is_preview_mode( $post_id = 0 ) {
184 if ( ! isset( $_GET['elementor-preview'] ) ) {
185 return false;
186 }
187
188 if ( empty( $post_id ) ) {
189 $post_id = get_the_ID();
190 }
191
192 if ( ! User::is_current_user_can_edit( $post_id ) ) {
193 return false;
194 }
195
196 if ( $post_id !== (int) $_GET['elementor-preview'] ) {
197 return false;
198 }
199
200 return true;
201 }
202
203 /**
204 * Whether WordPress post preview or Elementor preview iframe is active.
205 *
206 * @since 4.1.0
207 * @access public
208 *
209 * @return bool
210 */
211 public function is_editor_or_preview() {
212 return is_preview() || $this->is_preview_mode();
213 }
214
215 /**
216 * Builder wrapper.
217 *
218 * Used to add an empty HTML wrapper for the builder, the javascript will add
219 * the content later.
220 *
221 * @since 1.0.0
222 * @access public
223 *
224 * @param string $content The content of the builder.
225 *
226 * @return string HTML wrapper for the builder.
227 */
228 public function builder_wrapper( $content ) {
229 if ( get_the_ID() === $this->post_id ) {
230 $document = Plugin::$instance->documents->get( $this->post_id );
231
232 $attributes = $document->get_container_attributes();
233
234 $content = '<div ' . Utils::render_html_attributes( $attributes ) . '></div>';
235 }
236
237 return $content;
238 }
239
240 /**
241 * Enqueue preview styles.
242 *
243 * Registers all the preview styles and enqueues them.
244 *
245 * Fired by `wp_enqueue_scripts` action.
246 *
247 * @since 1.0.0
248 * @access private
249 */
250 private function enqueue_styles() {
251 // Hold-on all jQuery plugins after all HTML markup render.
252 wp_add_inline_script( 'jquery-migrate', 'jQuery.holdReady( true );' );
253
254 Plugin::$instance->frontend->enqueue_styles();
255
256 Plugin::$instance->elements_manager->enqueue_elements_styles();
257
258 Plugin::$instance->widgets_manager->enqueue_widgets_styles();
259
260 $suffix = Utils::is_script_debug() ? '' : '.min';
261
262 $direction_suffix = is_rtl() ? '-rtl' : '';
263
264 wp_register_style(
265 'elementor-select2',
266 ELEMENTOR_ASSETS_URL . 'lib/e-select2/css/e-select2' . $suffix . '.css',
267 [],
268 '4.0.6-rc.1'
269 );
270
271 wp_register_style(
272 'editor-preview',
273 ELEMENTOR_ASSETS_URL . 'css/editor-preview' . $direction_suffix . $suffix . '.css',
274 [
275 'elementor-select2',
276 ],
277 ELEMENTOR_VERSION
278 );
279
280 wp_enqueue_style(
281 'e-theme-ui-light',
282 $this->get_css_assets_url( 'theme-light' ),
283 [],
284 ELEMENTOR_VERSION
285 );
286
287 wp_enqueue_style( 'editor-preview' );
288
289 // Handle the 'wp audio' in editor preview.
290 wp_enqueue_style( 'wp-mediaelement' );
291
292 /**
293 * Preview enqueue styles.
294 *
295 * Fires after Elementor preview styles are enqueued.
296 *
297 * @since 1.0.0
298 */
299 do_action( 'elementor/preview/enqueue_styles' );
300 }
301
302 /**
303 * Enqueue preview scripts.
304 *
305 * Registers all the preview scripts and enqueues them.
306 *
307 * Fired by `wp_enqueue_scripts` action.
308 *
309 * @since 1.5.4
310 * @access private
311 */
312 private function enqueue_scripts() {
313 Plugin::$instance->frontend->register_scripts();
314
315 Plugin::$instance->widgets_manager->enqueue_widgets_scripts();
316 Plugin::$instance->elements_manager->enqueue_elements_scripts();
317
318 $suffix = Utils::is_script_debug() ? '' : '.min';
319
320 wp_enqueue_script(
321 'elementor-inline-editor',
322 ELEMENTOR_ASSETS_URL . 'lib/inline-editor/js/inline-editor' . $suffix . '.js',
323 [],
324 ELEMENTOR_VERSION,
325 true
326 );
327
328 // Handle the 'wp audio' in editor preview.
329 wp_enqueue_script( 'wp-mediaelement' );
330
331 /**
332 * Preview enqueue scripts.
333 *
334 * Fires after Elementor preview scripts are enqueued.
335 *
336 * @since 1.5.4
337 */
338 do_action( 'elementor/preview/enqueue_scripts' );
339 }
340
341 public function rocket_loader_filter( $tag, $handle, $src ) {
342 return str_replace( '<script', '<script data-cfasync="false"', $tag );
343 }
344
345 /**
346 * Elementor Preview footer scripts and styles.
347 *
348 * Handle styles and scripts from frontend.
349 *
350 * Fired by `wp_footer` action.
351 *
352 * @since 2.0.9
353 * @access public
354 */
355 public function wp_footer() {
356 $frontend = Plugin::$instance->frontend;
357 if ( $frontend->has_elementor_in_page() ) {
358 // Has header/footer/widget-template - enqueue all style/scripts/fonts.
359 $frontend->wp_footer();
360 } else {
361 // Enqueue only scripts.
362 $frontend->enqueue_scripts();
363 }
364 }
365
366 /**
367 * Preview constructor.
368 *
369 * Initializing Elementor preview.
370 *
371 * @since 1.0.0
372 * @access public
373 */
374 public function __construct() {
375 add_action( 'template_redirect', [ $this, 'init' ], 0 );
376 }
377 }
378