PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents / 4.4.3
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents v4.4.3
4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 trunk 1.0.0 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 2.0.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.1.3 3.2.0 3.2.1 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9 4.0.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.14 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.0.9 4.1.0 4.1.1 4.1.10 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.3.0 4.3.1 4.4.0 4.4.1 4.4.10 4.4.11 4.4.2 4.4.3 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 4.5.0 4.5.1
embedpress / Core / AssetManager.php
embedpress / Core Last commit date
AssetManager.php 9 months ago LocalizationManager.php 9 months ago init.php 10 months ago
AssetManager.php
816 lines
1 <?php
2
3 namespace EmbedPress\Core;
4
5 // Include LocalizationManager
6 // require_once __DIR__ . '/LocalizationManager.php';
7
8 use Embedpress\Core\LocalizationManager;
9
10 /**
11 * EmbedPress Asset Manager
12 *
13 * Centralized asset management for JS/CSS files across blocks, Elementor, admin, and frontend
14 * Handles new build files from Vite build system
15 */
16 class AssetManager
17 {
18 /**
19 * Track which handles should be treated as ES modules
20 */
21 private static $module_handles = [];
22
23 /**
24 * Track if the global module filter has been added
25 */
26 private static $module_filter_added = false;
27
28 /**
29 * Asset definitions with context-based loading
30 */
31 private static $assets = [
32
33 // 🔧 Scripts (Ordered by Priority)
34 // ----------------------------------
35
36 // Vendor assets (copied to assets folder for consistency)
37 // Priority 1-5: Core vendor libraries
38 'plyr-css' => [
39 'file' => 'css/plyr.css',
40 'deps' => [],
41 'contexts' => ['frontend', 'elementor', 'editor'],
42 'type' => 'style',
43 'handle' => 'embedpress-plyr-css',
44 'priority' => 1,
45 ],
46 'carousel-vendor-css' => [
47 'file' => 'css/carousel.min.css',
48 'deps' => [],
49 'contexts' => ['frontend', 'elementor'],
50 'type' => 'style',
51 'handle' => 'embedpress-carousel-vendor-css',
52 'priority' => 1,
53 ],
54 'glider-css' => [
55 'file' => 'css/glider.min.css',
56 'deps' => [],
57 'contexts' => ['frontend', 'elementor'],
58 'type' => 'style',
59 'handle' => 'embedpress-glider-css',
60 'priority' => 1,
61 ],
62 'plyr-js' => [
63 'file' => 'js/vendor/plyr.js',
64 'deps' => ['jquery'],
65 'contexts' => ['frontend', 'elementor', 'editor'],
66 'type' => 'script',
67 'footer' => true,
68 'handle' => 'embedpress-plyr',
69 'priority' => 2,
70 ],
71 'plyr-polyfilled-js' => [
72 'file' => 'js/vendor/plyr.polyfilled.js',
73 'deps' => ['jquery'],
74 'contexts' => ['frontend', 'elementor', 'editor'],
75 'type' => 'script',
76 'footer' => true,
77 'handle' => 'embedpress-plyr-polyfilled',
78 'priority' => 2,
79 ],
80 'carousel-vendor-js' => [
81 'file' => 'js/vendor/carousel.min.js',
82 'deps' => ['jquery'],
83 'contexts' => ['frontend', 'elementor'],
84 'type' => 'script',
85 'footer' => true,
86 'handle' => 'embedpress-carousel-vendor',
87 'priority' => 2,
88 ],
89 'glider-js' => [
90 'file' => 'js/vendor/glider.min.js',
91 'deps' => ['jquery'],
92 'contexts' => ['frontend', 'elementor'],
93 'type' => 'script',
94 'footer' => true,
95 'handle' => 'embedpress-glider',
96 'priority' => 2,
97 ],
98 'pdfobject-js' => [
99 'file' => 'js/vendor/pdfobject.js',
100 'deps' => [],
101 'contexts' => ['frontend', 'elementor', 'editor'],
102 'type' => 'script',
103 'footer' => true,
104 'handle' => 'embedpress-pdfobject',
105 'priority' => 2,
106 ],
107 'vimeo-player-js' => [
108 'file' => 'js/vendor/vimeo-player.js',
109 'deps' => [],
110 'contexts' => ['frontend', 'elementor'],
111 'type' => 'script',
112 'footer' => true,
113 'handle' => 'embedpress-vimeo-player',
114 'priority' => 2,
115 ],
116 'ytiframeapi-js' => [
117 'file' => 'js/vendor/ytiframeapi.js',
118 'deps' => [],
119 'contexts' => ['frontend', 'elementor'],
120 'type' => 'script',
121 'footer' => true,
122 'handle' => 'embedpress-ytiframeapi',
123 'priority' => 2,
124 ],
125
126 // Priority 5-6: Main application build assets
127 'admin-js' => [
128 'file' => 'js/admin.build.js',
129 'deps' => [],
130 'contexts' => ['admin'],
131 'type' => 'script',
132 'footer' => true,
133 'handle' => 'embedpress-admin',
134 'priority' => 5,
135 'page' => 'embedpress'
136 ],
137 // Priority 7-10: Blocks
138 'blocks-js' => [
139 'file' => 'js/blocks.build.js',
140 'deps' => ['wp-blocks', 'wp-i18n', 'wp-element', 'wp-api-fetch', 'wp-is-shallow-equal', 'wp-editor', 'wp-components'],
141 'contexts' => ['editor', 'frontend'],
142 'type' => 'script',
143 'footer' => true,
144 'handle' => 'embedpress-blocks-editor',
145 'priority' => 10,
146 ],
147 'blocks-editor-style' => [
148 'file' => 'css/blocks.build.css',
149 'deps' => [],
150 'contexts' => ['editor'],
151 'type' => 'style',
152 'handle' => 'embedpress-blocks-editor-style',
153 'priority' => 10,
154 ],
155 'blocks-style' => [
156 'file' => 'css/blocks.build.css',
157 'deps' => [],
158 'contexts' => ['frontend', 'editor'],
159 'type' => 'style',
160 'handle' => 'embedpress-blocks-style',
161 'priority' => 10,
162 ],
163
164 // Priority 15-20: Legacy JS files
165 'admin-legacy-js' => [
166 'file' => 'js/admin.js',
167 'deps' => ['jquery'],
168 'contexts' => ['admin'],
169 'type' => 'script',
170 'footer' => true,
171 'handle' => 'embedpress-admin-legacy',
172 'priority' => 15,
173 'page' => 'embedpress'
174 ],
175 'ads-js' => [
176 'file' => 'js/sponsored.js',
177 'deps' => ['jquery', 'embedpress-front'],
178 'contexts' => ['editor', 'frontend', 'elementor'],
179 'type' => 'script',
180 'footer' => true,
181 'handle' => 'embedpress-ads',
182 'priority' => 16,
183 ],
184 'analytics-tracker-js' => [
185 'file' => 'js/analytics-tracker.js',
186 'deps' => ['jquery'],
187 'contexts' => ['frontend', 'elementor'],
188 'type' => 'script',
189 'footer' => true,
190 'handle' => 'embedpress-analytics-tracker',
191 'priority' => 15,
192 ],
193 'carousel-js' => [
194 'file' => 'js/carousel.js',
195 'deps' => ['jquery', 'embedpress-carousel-vendor'],
196 'contexts' => ['frontend', 'elementor'],
197 'type' => 'script',
198 'footer' => true,
199 'handle' => 'embedpress-carousel',
200 'priority' => 15,
201 ],
202 'documents-viewer-js' => [
203 'file' => 'js/documents-viewer-script.js',
204 'deps' => ['jquery'],
205 'contexts' => ['frontend', 'elementor'],
206 'type' => 'script',
207 'footer' => true,
208 'handle' => 'embedpress-documents-viewer',
209 'priority' => 15,
210 ],
211 'front-js' => [
212 'file' => 'js/front.js',
213 'deps' => ['jquery'],
214 'contexts' => ['frontend', 'editor', 'elementor'],
215 'type' => 'script',
216 'footer' => true,
217 'handle' => 'embedpress-front',
218 'priority' => 15,
219 ],
220 'gallery-justify-js' => [
221 'file' => 'js/gallery-justify.js',
222 'deps' => ['jquery'],
223 'contexts' => ['editor', 'frontend', 'elementor'],
224 'type' => 'script',
225 'footer' => true,
226 'handle' => 'embedpress-gallery-justify',
227 'priority' => 15,
228 ],
229 'gutenberg-script-js' => [
230 'file' => 'js/gutneberg-script.js',
231 'deps' => ['wp-blocks', 'wp-element'],
232 'contexts' => ['editor'],
233 'type' => 'script',
234 'footer' => true,
235 'handle' => 'embedpress-gutenberg-script',
236 'priority' => 15,
237 ],
238 'init-plyr-js' => [
239 'file' => 'js/initplyr.js',
240 'deps' => ['jquery', 'embedpress-plyr'],
241 'contexts' => ['frontend', 'elementor'],
242 'type' => 'script',
243 'footer' => true,
244 'handle' => 'embedpress-init-plyr',
245 'priority' => 15,
246 ],
247 'instafeed-js' => [
248 'file' => 'js/instafeed.js',
249 'deps' => ['jquery'],
250 'contexts' => ['frontend', 'elementor'],
251 'type' => 'script',
252 'footer' => true,
253 'handle' => 'embedpress-instafeed',
254 'priority' => 15,
255 ],
256 'license-js' => [
257 'file' => 'js/license.js',
258 'deps' => ['jquery'],
259 'contexts' => ['admin'],
260 'type' => 'script',
261 'footer' => true,
262 'handle' => 'embedpress-license',
263 'priority' => 15,
264 'page' => 'embedpress'
265 ],
266 'preview-js' => [
267 'file' => 'js/preview.js',
268 'deps' => ['jquery'],
269 'contexts' => ['classic_editor'],
270 'type' => 'script',
271 'footer' => true,
272 'handle' => 'embedpress-preview',
273 'priority' => 15,
274 ],
275 'settings-js' => [
276 'file' => 'js/settings.js',
277 'deps' => ['jquery', 'wp-color-picker'],
278 'contexts' => ['admin'],
279 'type' => 'script',
280 'footer' => true,
281 'handle' => 'embedpress-settings',
282 'priority' => 15,
283 'page' => 'embedpress'
284 ],
285
286 // 🎨 Styles (Ordered by Priority)
287 // ----------------------------------
288
289 // Build CSS files (analytics.build.css is handled by Analytics.php)
290
291 // Legacy CSS files
292 'admin-notices-css' => [
293 'file' => 'css/admin-notices.css',
294 'deps' => [],
295 'contexts' => ['admin'],
296 'type' => 'style',
297 'handle' => 'embedpress-admin-notices',
298 'priority' => 5,
299 'page' => 'embedpress'
300 ],
301
302 'el-icon-css' => [
303 'file' => 'css/el-icon.css',
304 'deps' => [],
305 'contexts' => ['elementor-editor'],
306 'type' => 'style',
307 'handle' => 'embedpress-el-icon',
308 'priority' => 5,
309 ],
310 'embedpress-elementor-css' => [
311 'file' => 'css/embedpress-elementor.css',
312 'deps' => [],
313 'contexts' => ['elementor'],
314 'type' => 'style',
315 'handle' => 'embedpress-elementor-css',
316 'priority' => 5,
317 ],
318 'embedpress-css' => [
319 'file' => 'css/embedpress.css',
320 'deps' => [],
321 'contexts' => ['editor', 'frontend', 'elementor'],
322 'type' => 'style',
323 'handle' => 'embedpress-css',
324 'priority' => 5,
325 ],
326 'modal-css' => [
327 'file' => 'css/modal.css',
328 'deps' => [],
329 'contexts' => ['editor', 'classic_editor'],
330 'type' => 'style',
331 'handle' => 'embedpress-classic-editor-modal',
332 'priority' => 6,
333 ],
334 'meetup-events-css' => [
335 'file' => 'css/meetup-events.css',
336 'deps' => ['embedpress-css'],
337 'contexts' => ['frontend', 'editor', 'elementor'],
338 'type' => 'style',
339 'handle' => 'embedpress-meetup-events',
340 'priority' => 6,
341 ],
342 'settings-icons-css' => [
343 'file' => 'css/settings-icons.css',
344 'deps' => [],
345 'contexts' => ['admin'],
346 'type' => 'style',
347 'handle' => 'embedpress-settings-icons',
348 'priority' => 5,
349 'page' => 'embedpress'
350 ],
351 'settings-css' => [
352 'file' => 'css/settings.css',
353 'deps' => [],
354 'contexts' => ['admin'],
355 'type' => 'style',
356 'handle' => 'embedpress-settings-css',
357 'priority' => 5,
358 'page' => 'embedpress'
359 ],
360 'admin-css' => [
361 'file' => 'css/admin.css',
362 'deps' => [],
363 'contexts' => ['admin'],
364 'type' => 'style',
365 'handle' => 'embedpress-admin-css',
366 'priority' => 5,
367 'page' => 'embedpress'
368 ],
369 ];
370
371 /**
372 * Initialize asset manager
373 */
374 public static function init()
375 {
376
377 // Use proper priorities to ensure correct load order
378 add_action('wp_enqueue_scripts', [__CLASS__, 'enqueue_frontend_assets'], 5);
379 add_action('admin_enqueue_scripts', [__CLASS__, 'enqueue_admin_assets'], 5);
380 add_action('admin_enqueue_scripts', [__CLASS__, 'enqueue_classic_editor_assets'], 5);
381 add_action('enqueue_block_assets', [__CLASS__, 'enqueue_block_assets'], 5);
382
383
384 add_action('enqueue_block_editor_assets', [__CLASS__, 'enqueue_editor_assets'], 5);
385
386 add_action('elementor/frontend/after_enqueue_styles', [__CLASS__, 'enqueue_elementor_assets'], 5);
387
388 add_action('elementor/editor/after_enqueue_styles', [__CLASS__, 'enqueue_elementor_editor_assets'], 5);
389 }
390
391 /**
392 * Enqueue frontend assets
393 */
394 public static function enqueue_frontend_assets()
395 {
396 self::enqueue_assets_for_context('frontend');
397
398 // Setup frontend localization
399 LocalizationManager::setup_frontend_localization();
400 }
401
402 /**
403 * Enqueue admin assets
404 */
405 public static function enqueue_admin_assets($hook = '')
406 {
407 self::enqueue_assets_for_context('admin', $hook);
408
409 // Load settings assets only on EmbedPress settings pages
410 if (strpos($hook, 'embedpress') !== false) {
411 self::enqueue_assets_for_context('settings', $hook);
412
413 // Ensure wp-color-picker is loaded for settings page
414 wp_enqueue_style('wp-color-picker');
415
416 // Ensure media scripts are loaded
417 if (!did_action('wp_enqueue_media')) {
418 wp_enqueue_media();
419 }
420 }
421
422 // Setup admin localization
423 LocalizationManager::setup_admin_localization($hook);
424 }
425
426 /**
427 * Enqueue block assets (both editor and frontend)
428 */
429 public static function enqueue_block_assets()
430 {
431 // This runs on both frontend and editor for blocks
432 // For frontend, we don't need the editor scripts
433 if (is_admin()) {
434 self::enqueue_assets_for_context('editor');
435 }
436 }
437
438 /**
439 * Enqueue editor-only assets
440 */
441 public static function enqueue_editor_assets()
442 {
443 // Ensure editor assets are loaded
444 self::enqueue_assets_for_context('editor');
445
446 // Setup editor localization
447 LocalizationManager::setup_editor_localization();
448 }
449
450 public static function enqueue_classic_editor_assets()
451 {
452
453 // Ensure editor assets are loaded
454 self::enqueue_assets_for_context('classic_editor');
455
456 // Setup editor localization
457 LocalizationManager::setup_editor_localization();
458 }
459
460 /**
461 * Enqueue Elementor frontend assets
462 */
463 public static function enqueue_elementor_assets()
464 {
465 self::enqueue_assets_for_context('elementor');
466
467 // Setup Elementor localization
468 LocalizationManager::setup_elementor_localization();
469 }
470
471 /**
472 * Enqueue Elementor editor assets
473 */
474 public static function enqueue_elementor_editor_assets()
475 {
476 // In Elementor editor, load elementor, editor, and elementor-editor contexts
477 self::enqueue_assets_for_context('elementor');
478 self::enqueue_assets_for_context('editor');
479 self::enqueue_assets_for_context('elementor-editor');
480
481 // Setup Elementor editor localization
482 LocalizationManager::setup_elementor_localization();
483 }
484
485 /**
486 * Enqueue assets for a specific context
487 */
488 private static function enqueue_assets_for_context($context, $hook = '')
489 {
490
491 $assets_to_enqueue = [];
492
493 // Collect assets for this context
494 foreach (self::$assets as $key => $asset) {
495 if (in_array($context, $asset['contexts'])) {
496 // Check if asset has page restriction
497 if (isset($asset['page']) && !empty($asset['page'])) {
498 // Only enqueue if we're on the specified page
499 if (strpos($hook, $asset['page']) !== false) {
500 $assets_to_enqueue[] = array_merge($asset, ['key' => $key]);
501 }
502 // If page doesn't match, don't enqueue this asset
503 } else {
504 // No page restriction, enqueue normally
505 $assets_to_enqueue[] = array_merge($asset, ['key' => $key]);
506 }
507 }
508 }
509
510 // Sort by priority
511 usort($assets_to_enqueue, function ($a, $b) {
512 return $a['priority'] - $b['priority'];
513 });
514
515 // Enqueue assets
516 foreach ($assets_to_enqueue as $asset) {
517 self::enqueue_single_asset($asset);
518 }
519 }
520
521 /**
522 * Enqueue a single asset
523 */
524 private static function enqueue_single_asset($asset)
525 {
526 $file_url = EMBEDPRESS_PLUGIN_DIR_URL . 'assets/' . $asset['file'];
527 $file_path = EMBEDPRESS_PLUGIN_DIR_PATH . '/assets/' . $asset['file'];
528
529 if (! file_exists($file_path)) {
530 return;
531 }
532
533
534
535 $version = filemtime($file_path);
536
537 // Check if we should load this asset based on current context
538 if (!self::should_load_asset($asset)) {
539 return;
540 }
541
542 // Enqueue asset
543 if ($asset['type'] === 'script') {
544 wp_enqueue_script(
545 $asset['handle'],
546 $file_url,
547 $asset['deps'],
548 $version,
549 ! empty($asset['footer'])
550 );
551
552 // Add module attribute for ES modules (only build files)
553 if (strpos($asset['file'], '.build.js') !== false) {
554 // Track this handle as a module
555 self::$module_handles[] = $asset['handle'];
556
557 // Add the global filter only once
558 if (!self::$module_filter_added) {
559 self::$module_filter_added = true;
560 add_filter('script_loader_tag', [__CLASS__, 'add_module_attribute'], 10, 2);
561 }
562 }
563 } elseif ($asset['type'] === 'style') {
564
565 wp_enqueue_style(
566 $asset['handle'],
567 $file_url,
568 $asset['deps'],
569 $version,
570 $asset['media'] ?? 'all'
571 );
572 }
573 }
574
575 /**
576 * Determine if an asset should be loaded based on current context
577 */
578 private static function should_load_asset($asset)
579 {
580 // Get current environment state
581 $is_admin = is_admin();
582 $is_elementor_editor = false;
583 $is_elementor_preview = false;
584 $is_gutenberg_editor = false;
585
586 // Check Elementor states
587 if (class_exists('\Elementor\Plugin')) {
588 $elementor = \Elementor\Plugin::$instance;
589
590 if (isset($elementor->editor)) {
591 $is_elementor_editor = $elementor->editor->is_edit_mode();
592 }
593
594 if (isset($elementor->preview)) {
595 $is_elementor_preview = $elementor->preview->is_preview_mode();
596 }
597 }
598
599 // Check if we're in Gutenberg editor
600 if ($is_admin) {
601 global $pagenow;
602 $is_gutenberg_editor = (
603 $pagenow === 'post.php' ||
604 $pagenow === 'post-new.php' ||
605 $pagenow === 'site-editor.php'
606 ) && function_exists('use_block_editor_for_post_type');
607
608 // Check if we're in classic editor (not Gutenberg)
609 $is_classic_editor = false;
610 if ($pagenow === 'post.php' || $pagenow === 'post-new.php') {
611 // Check if classic editor is being used
612 if (isset($_GET['classic-editor']) ||
613 (function_exists('use_block_editor_for_post_type') &&
614 isset($_GET['post']) &&
615 !use_block_editor_for_post_type(get_post_type($_GET['post'])))) {
616 $is_classic_editor = true;
617 }
618 // Also check if Classic Editor plugin is active and set to classic mode
619 if (class_exists('Classic_Editor') &&
620 get_option('classic-editor-replace') === 'classic') {
621 $is_classic_editor = true;
622 }
623 }
624 }
625
626 // Asset loading logic based on contexts
627 foreach ($asset['contexts'] as $context) {
628
629
630 switch ($context) {
631 case 'frontend':
632 // Load on frontend (not in any editor or admin)
633 if (!$is_admin && !$is_elementor_editor && !$is_elementor_preview) {
634 return true;
635 }
636 break;
637
638 case 'admin':
639 // Load in WordPress admin (but not in Elementor editor)
640 if ($is_admin && !$is_elementor_editor && !$is_elementor_preview) {
641 // Check if asset has page restriction
642 if (isset($asset['page'])) {
643 return self::is_embedpress_admin_page($asset['page']);
644 }
645 return true;
646 }
647 break;
648
649 case 'editor':
650 // Load in Gutenberg editor or when editing posts
651 if ($is_gutenberg_editor || ($is_admin && !$is_elementor_editor)) {
652 return true;
653 }
654 break;
655 case 'classic_editor':
656 // Load only in classic editor (TinyMCE)
657 if ($is_classic_editor) {
658 return true;
659 }
660 break;
661 case 'elementor':
662 // Load in Elementor editor, preview, or frontend when Elementor is rendering
663 if ($is_elementor_editor || $is_elementor_preview) {
664 return true;
665 }
666 // Also load on frontend if Elementor content is present
667 if (!$is_admin && self::has_elementor_content()) {
668 return true;
669 }
670 break;
671
672 case 'elementor-editor':
673 // Load only in Elementor editor (not preview or frontend)
674 if ($is_elementor_editor) {
675 return true;
676 }
677 break;
678
679 case 'settings':
680 // Load only on EmbedPress settings pages
681 if ($is_admin && !$is_elementor_editor && !$is_elementor_preview) {
682 return true;
683 }
684 break;
685 }
686 }
687
688 // Check if this is an individual block script and if it should be loaded
689 if (strpos($asset['handle'], 'embedpress-block-') === 0) {
690 return self::should_load_individual_block($asset['handle']);
691 }
692
693 return false;
694 }
695
696 /**
697 * Check if we're on an EmbedPress admin page
698 */
699 private static function is_embedpress_admin_page($page_type)
700 {
701 global $pagenow;
702
703 // Get current page
704 $current_page = isset($_GET['page']) ? $_GET['page'] : '';
705
706 switch ($page_type) {
707 case 'embedpress':
708 // Check if we're on any EmbedPress admin page
709 return (
710 strpos($current_page, 'embedpress') !== false ||
711 $pagenow === 'admin.php' && strpos($current_page, 'embedpress') !== false
712 );
713 case 'embedpress-analytics':
714 return $current_page === 'embedpress-analytics';
715 default:
716 return false;
717 }
718 }
719
720 /**
721 * Check if individual block should be loaded based on active blocks
722 */
723 private static function should_load_individual_block($handle)
724 {
725 // Get active blocks from settings
726 $elements = (array) get_option(EMBEDPRESS_PLG_NAME . ":elements", []);
727 $active_blocks = isset($elements['gutenberg']) ? (array) $elements['gutenberg'] : [];
728
729 // Map handles to block names
730 $block_map = [
731 'embedpress-block-embedpress' => 'embedpress',
732 'embedpress-block-document' => 'document',
733 'embedpress-block-pdf' => 'embedpress-pdf',
734 'embedpress-block-calendar' => 'embedpress-calendar',
735 'embedpress-block-google-docs' => 'google-docs',
736 'embedpress-block-google-drawings' => 'google-drawings',
737 'embedpress-block-google-forms' => 'google-forms',
738 'embedpress-block-google-maps' => 'google-maps',
739 'embedpress-block-google-sheets' => 'google-sheets',
740 'embedpress-block-google-slides' => 'google-slides',
741 'embedpress-block-twitch' => 'twitch',
742 'embedpress-block-wistia' => 'wistia',
743 'embedpress-block-youtube' => 'youtube'
744 ];
745
746 $block_name = isset($block_map[$handle]) ? $block_map[$handle] : '';
747
748 // If no block name found or no active blocks set, load all blocks (default behavior)
749 if (empty($block_name) || empty($active_blocks)) {
750 return true;
751 }
752
753 // Check if this specific block is active
754 return in_array($block_name, $active_blocks);
755 }
756
757 /**
758 * Check if current page has Elementor content
759 */
760 private static function has_elementor_content()
761 {
762 if (! class_exists('\Elementor\Plugin')) {
763 return false;
764 }
765
766 if (is_singular()) {
767 $post_id = get_the_ID();
768 if (empty($post_id) || ! is_numeric($post_id)) {
769 return false;
770 }
771
772 $document = \Elementor\Plugin::$instance->documents->get($post_id);
773
774 if ($document && method_exists($document, 'is_built_with_elementor')) {
775 return (bool) $document->is_built_with_elementor();
776 }
777 }
778
779 return false;
780 }
781
782
783 /**
784 * Get asset URL
785 */
786 public static function get_asset_url($file)
787 {
788 return EMBEDPRESS_PLUGIN_DIR_URL . 'assets/' . $file;
789 }
790
791
792
793 /**
794 * Add module attribute to script tags for ES modules
795 */
796 public static function add_module_attribute($tag, $handle)
797 {
798 if (in_array($handle, self::$module_handles)) {
799 // Only add type="module" if it doesn't already exist
800 if (strpos($tag, 'type="module"') === false) {
801 return str_replace('<script ', '<script type="module" ', $tag);
802 }
803 }
804 return $tag;
805 }
806
807 /**
808 * Check if asset exists
809 */
810 public static function asset_exists($file)
811 {
812 $plugin_path = dirname(dirname(dirname(__DIR__)));
813 return file_exists($plugin_path . '/assets/' . $file);
814 }
815 }
816