| @@ -3,10 +3,11 @@ | ||
| 3 | 3 | |
| 4 | 4 | use Elementor\Core\Breakpoints\Manager as Breakpoints_Manager; |
| 5 | 5 | use Elementor\Core\Common\Modules\Ajax\Module; |
| 6 | 6 | use Elementor\Core\Debug\Loading_Inspection_Manager; |
| 7 | -use Elementor\Core\Editor\Loader\Editor_Loader_Factory; | |
| 8 | -use Elementor\Core\Editor\Loader\Editor_Loader_Interface; | |
| 7 | +use Elementor\Core\Editor\Loader\Editor_Loader; | |
| 8 | +use Elementor\Core\Utils\Assets_Config_Provider; | |
| 9 | +use Elementor\Core\Utils\Collection; | |
| 9 | 10 | use Elementor\Core\Settings\Manager as SettingsManager; |
| 10 | 11 | use Elementor\Plugin; |
| 11 | 12 | use Elementor\TemplateLibrary\Source_Local; |
| 12 | 13 | use Elementor\Utils; |
| @@ -65,9 +66,9 @@ | ||
| 65 | 66 | */ |
| 66 | 67 | public $promotion; |
| 67 | 68 | |
| 68 | 69 | /** |
| 69 | - * @var Editor_Loader_Interface | |
| 70 | + * @var Editor_Loader | |
| 70 | 71 | */ |
| 71 | 72 | private $loader; |
| 72 | 73 | |
| 73 | 74 | /** |
| @@ -116,8 +117,10 @@ | ||
| 116 | 117 | |
| 117 | 118 | // Send MIME Type header like WP admin-header. |
| 118 | 119 | @header( 'Content-Type: ' . get_option( 'html_type' ) . '; charset=' . get_option( 'blog_charset' ) ); |
| 119 | 120 | |
| 121 | + self::send_document_isolation_policy_header(); | |
| 122 | + | |
| 120 | 123 | add_filter( 'show_admin_bar', '__return_false' ); |
| 121 | 124 | |
| 122 | 125 | // Remove all WordPress actions |
| 123 | 126 | remove_all_actions( 'wp_head' ); |
| @@ -209,8 +212,67 @@ | ||
| 209 | 212 | die; |
| 210 | 213 | } |
| 211 | 214 | |
| 212 | 215 | /** |
| 216 | + * Whether the current request targets the Elementor editor. | |
| 217 | + * | |
| 218 | + * Unlike `is_edit_mode()`, this is not affected by temporary `set_edit_mode()` overrides. | |
| 219 | + * | |
| 220 | + * @since 4.1.0 | |
| 221 | + * @access public | |
| 222 | + * | |
| 223 | + * @return bool Whether the current request targets the Elementor editor. | |
| 224 | + */ | |
| 225 | + public function is_editor_request() { | |
| 226 | + $common = Plugin::$instance->common; | |
| 227 | + | |
| 228 | + if ( $common ) { | |
| 229 | + /** @var Module ajax */ | |
| 230 | + $ajax_data = $common->get_component( 'ajax' )->get_current_action_data(); | |
| 231 | + | |
| 232 | + if ( ! empty( $ajax_data ) && 'get_document_config' === $ajax_data['action'] ) { | |
| 233 | + return true; | |
| 234 | + } | |
| 235 | + } | |
| 236 | + | |
| 237 | + if ( $this->is_editor_admin_screen() ) { | |
| 238 | + return true; | |
| 239 | + } | |
| 240 | + | |
| 241 | + return $this->is_editor_ajax_request(); | |
| 242 | + } | |
| 243 | + | |
| 244 | + private function is_editor_admin_screen(): bool { | |
| 245 | + if ( ! function_exists( 'get_current_screen' ) ) { | |
| 246 | + return false; | |
| 247 | + } | |
| 248 | + | |
| 249 | + $screen = get_current_screen(); | |
| 250 | + | |
| 251 | + if ( ! $screen ) { | |
| 252 | + return false; | |
| 253 | + } | |
| 254 | + | |
| 255 | + return isset( $_GET['action'] ) && 'elementor' === $_GET['action'] && in_array( $screen->base, [ 'post', 'toplevel_page_elementor' ], true ); | |
| 256 | + } | |
| 257 | + | |
| 258 | + private function is_editor_ajax_request(): bool { | |
| 259 | + $actions = apply_filters( 'elementor/editor/ajax_actions', [ | |
| 260 | + 'elementor', | |
| 261 | + | |
| 262 | + // Templates | |
| 263 | + 'elementor_get_templates', | |
| 264 | + 'elementor_save_template', | |
| 265 | + 'elementor_get_template', | |
| 266 | + 'elementor_delete_template', | |
| 267 | + 'elementor_import_template', | |
| 268 | + 'elementor_library_direct_actions', | |
| 269 | + ] ); | |
| 270 | + | |
| 271 | + return isset( $_REQUEST['action'] ) && in_array( $_REQUEST['action'], $actions, true ); | |
| 272 | + } | |
| 273 | + | |
| 274 | + /** | |
| 213 | 275 | * Whether the edit mode is active. |
| 214 | 276 | * |
| 215 | 277 | * Used to determine whether we are in the edit mode. |
| 216 | 278 | * |
| @@ -542,8 +604,66 @@ | ||
| 542 | 604 | add_filter( 'replace_editor', [ $this, 'filter_replace_editor' ], 10, 2 ); |
| 543 | 605 | } |
| 544 | 606 | |
| 545 | 607 | /** |
| 608 | + * Whether the Document-Isolation-Policy header should be sent on the | |
| 609 | + * Elementor editor screen and the editor preview iframe. | |
| 610 | + * | |
| 611 | + * DIP places the document in its own agent cluster, which is the prerequisite | |
| 612 | + * for cross-origin isolation features such as SharedArrayBuffer (required by | |
| 613 | + * WordPress core's client-side media processing introduced in WP 7.1). | |
| 614 | + * | |
| 615 | + * Both the editor parent document and the preview iframe must send the same | |
| 616 | + * DIP header so they join the same agent cluster and synchronous DOM access | |
| 617 | + * between them (e.g. `iframe.contentWindow.elementorFrontend`) keeps working. | |
| 618 | + * | |
| 619 | + * The header is only honored by browsers on a secure context (HTTPS or | |
| 620 | + * localhost) so the helper short-circuits on insecure origins to avoid | |
| 621 | + * sending a header that the browser will ignore. | |
| 622 | + * | |
| 623 | + * @since 4.1.0 | |
| 624 | + * | |
| 625 | + * @return bool | |
| 626 | + */ | |
| 627 | + public static function should_use_document_isolation_policy() { | |
| 628 | + if ( ! is_ssl() ) { | |
| 629 | + $raw_host = isset( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : ''; | |
| 630 | + $host = strtolower( (string) strtok( $raw_host, ':' ) ); | |
| 631 | + | |
| 632 | + if ( 'localhost' !== $host && ! str_ends_with( $host, '.localhost' ) ) { | |
| 633 | + return false; | |
| 634 | + } | |
| 635 | + } | |
| 636 | + | |
| 637 | + /** | |
| 638 | + * Filters whether Elementor sends the Document-Isolation-Policy header | |
| 639 | + * on the editor screen and preview iframe. | |
| 640 | + * | |
| 641 | + * @since 4.1.0 | |
| 642 | + * | |
| 643 | + * @param bool $enabled Whether DIP is enabled. Defaults to true on a secure context. | |
| 644 | + */ | |
| 645 | + return (bool) apply_filters( 'elementor/editor/use_document_isolation_policy', true ); | |
| 646 | + } | |
| 647 | + | |
| 648 | + /** | |
| 649 | + * Send the Document-Isolation-Policy header for the current response. | |
| 650 | + * | |
| 651 | + * Safe to call from both the Elementor editor screen handler and the | |
| 652 | + * preview iframe handler. No-op when {@see self::should_use_document_isolation_policy()} | |
| 653 | + * returns false. | |
| 654 | + * | |
| 655 | + * @since 4.1.0 | |
| 656 | + */ | |
| 657 | + public static function send_document_isolation_policy_header() { | |
| 658 | + if ( ! self::should_use_document_isolation_policy() || headers_sent() ) { | |
| 659 | + return; | |
| 660 | + } | |
| 661 | + | |
| 662 | + header( 'Document-Isolation-Policy: isolate-and-credentialless' ); | |
| 663 | + } | |
| 664 | + | |
| 665 | + /** | |
| 546 | 666 | * Signals to WordPress that Elementor is replacing the block editor on its own editor page, |
| 547 | 667 | * so that block-editor-specific behaviour (e.g. WP 7.0 COOP/COEP isolation headers) is not |
| 548 | 668 | * applied when the Elementor editor is active. |
| 549 | 669 | * |
| @@ -600,13 +720,24 @@ | ||
| 600 | 720 | |
| 601 | 721 | /** |
| 602 | 722 | * Get loader. |
| 603 | 723 | * |
| 604 | - * @return Editor_Loader_Interface | |
| 724 | + * @return Editor_Loader | |
| 605 | 725 | */ |
| 606 | 726 | private function get_loader() { |
| 607 | 727 | if ( ! $this->loader ) { |
| 608 | - $this->loader = Editor_Loader_Factory::create(); | |
| 728 | + $this->loader = new Editor_Loader( | |
| 729 | + new Collection( [ | |
| 730 | + 'assets_url' => ELEMENTOR_ASSETS_URL, | |
| 731 | + 'min_suffix' => ( Utils::is_script_debug() || Utils::is_elementor_tests() ) ? '' : '.min', | |
| 732 | + 'direction_suffix' => is_rtl() ? '-rtl' : '', | |
| 733 | + ] ), | |
| 734 | + ( new Assets_Config_Provider() )->set_path_resolver( | |
| 735 | + function ( $name ) { | |
| 736 | + return ELEMENTOR_ASSETS_PATH . "js/packages/{$name}/{$name}.asset.php"; | |
| 737 | + } | |
| 738 | + ) | |
| 739 | + ); | |
| 609 | 740 | |
| 610 | 741 | $this->loader->init(); |
| 611 | 742 | } |
| 612 | 743 | |