| @@ -5,8 +5,9 @@ | ||
| 5 | 5 | use Elementor\Core\Common\Modules\Ajax\Module; |
| 6 | 6 | use Elementor\Core\Debug\Loading_Inspection_Manager; |
| 7 | 7 | use Elementor\Core\Editor\Loader\Editor_Loader_Factory; |
| 8 | 8 | use Elementor\Core\Editor\Loader\Editor_Loader_Interface; |
| 9 | +use Elementor\Core\Experiments\Manager as Experiments_Manager; | |
| 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; |
| @@ -30,8 +31,10 @@ | ||
| 30 | 31 | * User capability required to access Elementor editor. |
| 31 | 32 | */ |
| 32 | 33 | const EDITING_CAPABILITY = 'edit_posts'; |
| 33 | 34 | |
| 35 | + const EDITOR_V2_EXPERIMENT_NAME = 'editor_v2'; | |
| 36 | + | |
| 34 | 37 | /** |
| 35 | 38 | * Post ID. |
| 36 | 39 | * |
| 37 | 40 | * Holds the ID of the current post being edited. |
| @@ -80,11 +83,11 @@ | ||
| 80 | 83 | * |
| 81 | 84 | * @since 1.0.0 |
| 82 | 85 | * @access public |
| 83 | 86 | * |
| 84 | - * @param bool $to_die Optional. Whether to die at the end. Default is `true`. | |
| 87 | + * @param bool $die Optional. Whether to die at the end. Default is `true`. | |
| 85 | 88 | */ |
| 86 | - public function init( $to_die = true ) { | |
| 89 | + public function init( $die = true ) { | |
| 87 | 90 | if ( empty( $_REQUEST['post'] ) ) { |
| 88 | 91 | return; |
| 89 | 92 | } |
| 90 | 93 | |
| @@ -116,10 +119,8 @@ | ||
| 116 | 119 | |
| 117 | 120 | // Send MIME Type header like WP admin-header. |
| 118 | 121 | @header( 'Content-Type: ' . get_option( 'html_type' ) . '; charset=' . get_option( 'blog_charset' ) ); |
| 119 | 122 | |
| 120 | - self::send_document_isolation_policy_header(); | |
| 121 | - | |
| 122 | 123 | add_filter( 'show_admin_bar', '__return_false' ); |
| 123 | 124 | |
| 124 | 125 | // Remove all WordPress actions |
| 125 | 126 | remove_all_actions( 'wp_head' ); |
| @@ -161,9 +162,9 @@ | ||
| 161 | 162 | |
| 162 | 163 | $this->get_loader()->print_root_template(); |
| 163 | 164 | |
| 164 | 165 | // From the action it's an empty string, from tests its `false` |
| 165 | - if ( false !== $to_die ) { | |
| 166 | + if ( false !== $die ) { | |
| 166 | 167 | die; |
| 167 | 168 | } |
| 168 | 169 | } |
| 169 | 170 | |
| @@ -536,92 +537,16 @@ | ||
| 536 | 537 | |
| 537 | 538 | add_action( 'admin_action_elementor', [ $this, 'init' ] ); |
| 538 | 539 | add_action( 'template_redirect', [ $this, 'redirect_to_new_url' ] ); |
| 539 | 540 | |
| 541 | + $this->register_editor_v2_experiment(); | |
| 542 | + | |
| 540 | 543 | // Handle autocomplete feature for URL control. |
| 541 | 544 | add_filter( 'wp_link_query_args', [ $this, 'filter_wp_link_query_args' ] ); |
| 542 | 545 | add_filter( 'wp_link_query', [ $this, 'filter_wp_link_query' ] ); |
| 543 | - | |
| 544 | - add_filter( 'replace_editor', [ $this, 'filter_replace_editor' ], 10, 2 ); | |
| 545 | 546 | } |
| 546 | 547 | |
| 547 | 548 | /** |
| 548 | - * Whether the Document-Isolation-Policy header should be sent on the | |
| 549 | - * Elementor editor screen and the editor preview iframe. | |
| 550 | - * | |
| 551 | - * DIP places the document in its own agent cluster, which is the prerequisite | |
| 552 | - * for cross-origin isolation features such as SharedArrayBuffer (required by | |
| 553 | - * WordPress core's client-side media processing introduced in WP 7.1). | |
| 554 | - * | |
| 555 | - * Both the editor parent document and the preview iframe must send the same | |
| 556 | - * DIP header so they join the same agent cluster and synchronous DOM access | |
| 557 | - * between them (e.g. `iframe.contentWindow.elementorFrontend`) keeps working. | |
| 558 | - * | |
| 559 | - * The header is only honored by browsers on a secure context (HTTPS or | |
| 560 | - * localhost) so the helper short-circuits on insecure origins to avoid | |
| 561 | - * sending a header that the browser will ignore. | |
| 562 | - * | |
| 563 | - * @since 4.1.0 | |
| 564 | - * | |
| 565 | - * @return bool | |
| 566 | - */ | |
| 567 | - public static function should_use_document_isolation_policy() { | |
| 568 | - if ( ! is_ssl() ) { | |
| 569 | - $raw_host = isset( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : ''; | |
| 570 | - $host = strtolower( (string) strtok( $raw_host, ':' ) ); | |
| 571 | - | |
| 572 | - if ( 'localhost' !== $host && ! str_ends_with( $host, '.localhost' ) ) { | |
| 573 | - return false; | |
| 574 | - } | |
| 575 | - } | |
| 576 | - | |
| 577 | - /** | |
| 578 | - * Filters whether Elementor sends the Document-Isolation-Policy header | |
| 579 | - * on the editor screen and preview iframe. | |
| 580 | - * | |
| 581 | - * @since 4.1.0 | |
| 582 | - * | |
| 583 | - * @param bool $enabled Whether DIP is enabled. Defaults to true on a secure context. | |
| 584 | - */ | |
| 585 | - return (bool) apply_filters( 'elementor/editor/use_document_isolation_policy', true ); | |
| 586 | - } | |
| 587 | - | |
| 588 | - /** | |
| 589 | - * Send the Document-Isolation-Policy header for the current response. | |
| 590 | - * | |
| 591 | - * Safe to call from both the Elementor editor screen handler and the | |
| 592 | - * preview iframe handler. No-op when {@see self::should_use_document_isolation_policy()} | |
| 593 | - * returns false. | |
| 594 | - * | |
| 595 | - * @since 4.1.0 | |
| 596 | - */ | |
| 597 | - public static function send_document_isolation_policy_header() { | |
| 598 | - if ( ! self::should_use_document_isolation_policy() || headers_sent() ) { | |
| 599 | - return; | |
| 600 | - } | |
| 601 | - | |
| 602 | - header( 'Document-Isolation-Policy: isolate-and-credentialless' ); | |
| 603 | - } | |
| 604 | - | |
| 605 | - /** | |
| 606 | - * Signals to WordPress that Elementor is replacing the block editor on its own editor page, | |
| 607 | - * so that block-editor-specific behaviour (e.g. WP 7.0 COOP/COEP isolation headers) is not | |
| 608 | - * applied when the Elementor editor is active. | |
| 609 | - * | |
| 610 | - * @param bool $replace Whether the editor is being replaced. | |
| 611 | - * @param \WP_Post $post The post being edited. | |
| 612 | - * | |
| 613 | - * @return bool | |
| 614 | - */ | |
| 615 | - public function filter_replace_editor( $replace, $post ) { | |
| 616 | - if ( isset( $_REQUEST['action'] ) && 'elementor' === $_REQUEST['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 617 | - return true; | |
| 618 | - } | |
| 619 | - | |
| 620 | - return $replace; | |
| 621 | - } | |
| 622 | - | |
| 623 | - /** | |
| 624 | 549 | * @since 2.2.0 |
| 625 | 550 | * @access public |
| 626 | 551 | */ |
| 627 | 552 | public function filter_wp_link_query_args( $query ) { |
| @@ -670,8 +595,28 @@ | ||
| 670 | 595 | $this->loader->init(); |
| 671 | 596 | } |
| 672 | 597 | |
| 673 | 598 | return $this->loader; |
| 599 | + } | |
| 600 | + | |
| 601 | + /** | |
| 602 | + * Adding Editor V2 experiment. | |
| 603 | + * | |
| 604 | + * @return void | |
| 605 | + * @throws \Exception | |
| 606 | + */ | |
| 607 | + private function register_editor_v2_experiment() { | |
| 608 | + Plugin::$instance->experiments->add_feature( [ | |
| 609 | + 'name' => static::EDITOR_V2_EXPERIMENT_NAME, | |
| 610 | + 'title' => esc_html__( 'Editor Top Bar', 'elementor' ), | |
| 611 | + 'description' => sprintf( | |
| 612 | + '%1$s <a href="https://go.elementor.com/wp-dash-elementor-top-bar/" target="_blank">%2$s</a>', | |
| 613 | + esc_html__( 'Get a sneak peek of the new Editor powered by React. The beautiful design and experimental layout of the Top bar are just some of the exciting tools on their way.', 'elementor' ), | |
| 614 | + esc_html__( 'Learn more', 'elementor' ) | |
| 615 | + ), | |
| 616 | + 'default' => Experiments_Manager::STATE_INACTIVE, | |
| 617 | + 'release_status' => Experiments_Manager::RELEASE_STATUS_BETA, | |
| 618 | + ] ); | |
| 674 | 619 | } |
| 675 | 620 | |
| 676 | 621 | /** |
| 677 | 622 | * Get elements presets. |