diff --git a/backport-changelog/7.0/11161.md b/backport-changelog/7.0/11161.md new file mode 100644 index 00000000000000..20313d2cae9c1e --- /dev/null +++ b/backport-changelog/7.0/11161.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/11161 + +* https://github.com/WordPress/gutenberg/pull/75739 diff --git a/lib/compat/wordpress-7.0/collaboration.php b/lib/compat/wordpress-7.0/collaboration.php index 4d123d51674ebe..90eb2d8533905c 100644 --- a/lib/compat/wordpress-7.0/collaboration.php +++ b/lib/compat/wordpress-7.0/collaboration.php @@ -134,18 +134,19 @@ function () use ( $option_name ) { ); } add_action( 'admin_init', 'gutenberg_register_real_time_collaboration_setting' ); +} - /** - * Injects the real-time collaboration setting into a global variable. - */ - function gutenberg_inject_real_time_collaboration_setting() { - if ( get_option( 'wp_enable_real_time_collaboration', '0' ) ) { - wp_add_inline_script( - 'wp-core-data', - 'window._wpCollaborationEnabled = true;', - 'after' - ); - } +/** + * Injects the real-time collaboration setting into a global variable. + */ +function gutenberg_inject_real_time_collaboration_setting() { + if ( get_option( 'wp_enable_real_time_collaboration' ) ) { + wp_add_inline_script( + 'wp-core-data', + 'window._wpCollaborationEnabled = true;', + 'after' + ); } - add_action( 'admin_init', 'gutenberg_inject_real_time_collaboration_setting' ); } +add_action( 'admin_init', 'gutenberg_inject_real_time_collaboration_setting' ); +add_filter( 'default_option_wp_enable_real_time_collaboration', '__return_true' ); diff --git a/lib/upgrade.php b/lib/upgrade.php index 9450c1c89439c1..51841efb25d15f 100644 --- a/lib/upgrade.php +++ b/lib/upgrade.php @@ -62,23 +62,3 @@ function _gutenberg_migrate_remove_fse_drafts() { delete_option( 'gutenberg_last_synchronize_theme_template_checks' ); delete_option( 'gutenberg_last_synchronize_theme_template-part_checks' ); } - -/** - * Replace unprefixed option enable_real_time_collaboration with prefixed version. - * - * Adds a `wp_` prefix to the option name to follow the convention for adding new - * options to WordPress since WP 5.8.0. - * - * @since 22.6.0 - */ -function _gutenberg_migrate_enable_real_time_collaboration() { - $current_value = get_option( 'enable_real_time_collaboration', '0' ); - - update_option( 'wp_enable_real_time_collaboration', $current_value ); - delete_option( 'enable_real_time_collaboration' ); -} - -// Deletion of the `_wp_file_based` term (in _gutenberg_migrate_remove_fse_drafts) must happen -// after its taxonomy (`wp_theme`) is registered. This happens in `gutenberg_register_wp_theme_taxonomy`, -// which is hooked into `init` (default priority, i.e. 10). -add_action( 'init', '_gutenberg_migrate_database', 20 ); diff --git a/packages/core-data/src/utils/crdt.ts b/packages/core-data/src/utils/crdt.ts index eb892f7d47d055..36ccbe4c49e277 100644 --- a/packages/core-data/src/utils/crdt.ts +++ b/packages/core-data/src/utils/crdt.ts @@ -351,11 +351,8 @@ export function getPostChangesFromCRDTDoc( // Do not overwrite a "floating" date. Borrowing logic from the // isEditedPostDateFloating selector. const currentDateIsFloating = - [ 'draft', 'auto-draft', 'pending' ].includes( - ymap.get( 'status' ) as string - ) && - ( null === currentValue || - editedRecord.modified === currentValue ); + null === currentValue || + editedRecord.modified === currentValue; if ( currentDateIsFloating ) { return false; diff --git a/test/e2e/specs/editor/collaboration/collaboration-metabox-lock.spec.ts b/test/e2e/specs/editor/collaboration/collaboration-metabox-lock.spec.ts index eaf499e1c1569f..e2d1a9f8166c3b 100644 --- a/test/e2e/specs/editor/collaboration/collaboration-metabox-lock.spec.ts +++ b/test/e2e/specs/editor/collaboration/collaboration-metabox-lock.spec.ts @@ -22,10 +22,6 @@ test.describe( 'Collaboration with meta boxes', () => { editor, page, } ) => { - // Ensure collaboration is enabled (the fixture enables it, but - // be explicit to match the pattern of other collaboration tests). - await collaborationUtils.setCollaboration( true ); - // Create a draft post. const post = await requestUtils.createPost( { title: 'Meta Box Lock Test', @@ -43,6 +39,9 @@ test.describe( 'Collaboration with meta boxes', () => { fullscreenMode: false, } ); + // Wait for collaboration runtime and entity record to be ready. + await collaborationUtils.waitForEntityReady( page ); + // Wait for meta boxes to initialize and disable collaboration. // collaborationSupported starts as true, then the meta box hook // sets it to false once meta boxes are detected. diff --git a/test/e2e/specs/editor/collaboration/fixtures/collaboration-utils.ts b/test/e2e/specs/editor/collaboration/fixtures/collaboration-utils.ts index c7ec6c5d8c9871..0b2b3a24779cf4 100644 --- a/test/e2e/specs/editor/collaboration/fixtures/collaboration-utils.ts +++ b/test/e2e/specs/editor/collaboration/fixtures/collaboration-utils.ts @@ -50,51 +50,6 @@ export default class CollaborationUtils { this.primaryPage = page; } - /** - * Set the real-time collaboration WordPress setting. - * - * Uses the form-based approach (similar to setGutenbergExperiments) - * because this setting is registered on admin_init in the "writing" - * group and is not exposed via /wp/v2/settings. - * - * @param enabled Whether to enable or disable collaboration. - */ - async setCollaboration( enabled: boolean ) { - const response = await this.requestUtils.request.get( - '/wp-admin/options-writing.php' - ); - const html = await response.text(); - const nonce = html.match( /name="_wpnonce" value="([^"]+)"/ )![ 1 ]; - - // WordPress core (7.0+) uses 'enable_real_time_collaboration', - // while the Gutenberg plugin uses 'wp_enable_real_time_collaboration'. - // Detect which field name is present on the page. - const optionName = html.includes( - 'name="enable_real_time_collaboration"' - ) - ? 'enable_real_time_collaboration' - : 'wp_enable_real_time_collaboration'; - - const formData: Record< string, string | number > = { - option_page: 'writing', - action: 'update', - _wpnonce: nonce, - _wp_http_referer: '/wp-admin/options-writing.php', - submit: 'Save Changes', - default_category: 1, - default_post_format: 0, - }; - - if ( enabled ) { - formData[ optionName ] = 1; - } - - await this.requestUtils.request.post( '/wp-admin/options.php', { - form: formData, - failOnStatusCode: true, - } ); - } - /** * Open a collaborative editing session where both the primary user (admin) * and the second user (collaborator) are editing the same post. @@ -355,7 +310,47 @@ export default class CollaborationUtils { this.secondPage = null; this.secondEditor = null; } - await this.setCollaboration( false ); await this.requestUtils.deleteAllUsers(); } } + +/** + * Set the real-time collaboration WordPress setting. + * + * Uses the form-based approach (similar to setGutenbergExperiments) + * because this setting is registered on admin_init in the "writing" + * group and is not exposed via /wp/v2/settings. + * + * @param requestUtils An instance of RequestUtils for making HTTP requests. + * @param enabled Whether to enable or disable collaboration. + */ +export async function setCollaboration( + requestUtils: RequestUtils, + enabled: boolean +): Promise< void > { + const response = await requestUtils.request.get( + '/wp-admin/options-writing.php' + ); + const html = await response.text(); + const nonce = html.match( /name="_wpnonce" value="([^"]+)"/ )![ 1 ]; + + const optionName = 'wp_enable_real_time_collaboration'; + const optionValue = enabled ? 1 : 0; + + const formData: Record< string, string | number > = { + option_page: 'writing', + action: 'update', + _wpnonce: nonce, + _wp_http_referer: '/wp-admin/options-writing.php', + submit: 'Save Changes', + default_category: 1, + default_post_format: 0, + }; + + formData[ optionName ] = optionValue; + + await requestUtils.request.post( '/wp-admin/options.php', { + form: formData, + failOnStatusCode: true, + } ); +} diff --git a/test/e2e/specs/editor/collaboration/fixtures/index.ts b/test/e2e/specs/editor/collaboration/fixtures/index.ts index 335cf21f375b29..fcd523fb96fd24 100644 --- a/test/e2e/specs/editor/collaboration/fixtures/index.ts +++ b/test/e2e/specs/editor/collaboration/fixtures/index.ts @@ -24,7 +24,6 @@ export const test = base.extend< Fixtures >( { requestUtils, page, } ); - await utils.setCollaboration( true ); // Clean up any leftover users from previous runs before creating. await requestUtils.deleteAllUsers(); await requestUtils.createUser( SECOND_USER ); diff --git a/test/e2e/specs/editor/plugins/block-hooks.spec.js b/test/e2e/specs/editor/plugins/block-hooks.spec.js index 971dc5d764fd70..f56a1513f4dfea 100644 --- a/test/e2e/specs/editor/plugins/block-hooks.spec.js +++ b/test/e2e/specs/editor/plugins/block-hooks.spec.js @@ -3,6 +3,13 @@ */ const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); +/** + * Internal dependencies + */ +const { + setCollaboration, +} = require( '../../editor/collaboration/fixtures/collaboration-utils' ); + const dummyBlocksContent = `

This is a dummy heading

@@ -65,6 +72,12 @@ test.describe( 'Block Hooks API', () => { } else { containerPost = postObject; } + + /** + * Since the Block Hooks API relies on server-side rendering to insert + * the hooked blocks, there is a fundamental incompatibility with RTC. + */ + await setCollaboration( requestUtils, false ); } ); test.afterAll( async ( { requestUtils } ) => { @@ -74,6 +87,7 @@ test.describe( 'Block Hooks API', () => { await requestUtils.deleteAllPosts(); await requestUtils.deleteAllBlocks(); + await setCollaboration( requestUtils, true ); } ); test( `should insert hooked blocks into ${ name } on frontend`, async ( { @@ -198,6 +212,12 @@ test.describe( 'Block Hooks API', () => { } else { containerPost = postObject; } + + /** + * Since the Block Hooks API relies on server-side rendering to insert + * the hooked blocks, there is a fundamental incompatibility with RTC. + */ + await setCollaboration( requestUtils, false ); } ); test.afterAll( async ( { requestUtils } ) => { @@ -207,6 +227,7 @@ test.describe( 'Block Hooks API', () => { await requestUtils.deleteAllPosts(); await requestUtils.deleteAllBlocks(); + await setCollaboration( requestUtils, true ); } ); test( `should insert hooked blocks into ${ name } on frontend`, async ( { diff --git a/test/e2e/specs/editor/various/inner-blocks-templates.spec.js b/test/e2e/specs/editor/various/inner-blocks-templates.spec.js index eb34b00e8e69dc..1a7609ab837d1d 100644 --- a/test/e2e/specs/editor/various/inner-blocks-templates.spec.js +++ b/test/e2e/specs/editor/various/inner-blocks-templates.spec.js @@ -11,7 +11,9 @@ test.describe( 'Inner blocks templates', () => { } ); test.beforeEach( async ( { admin } ) => { - await admin.createNewPost(); + await admin.createNewPost( { + postType: 'page', + } ); } ); test.afterAll( async ( { requestUtils } ) => {