WordPress/wordpress-playground

[Safari] Post editor only shows the code editing mode

adamziel opened this issue · 8 comments

@gziolo reported the following behavior:

For some reason when I load the post editor, it shows only code editing mode. I can’t enable the visual mode.

Screen Shot 2022-09-21 at 11 27 33

I can't reproduce on the latest trunk anymore so I'm closing this one. @gziolo feel free to reopen if you're still experiencing this issue.

It's still an issue when I test in Safari on MacOS when using https://wasm.wordpress.net/wordpress-browser.html:

Screen Shot 2022-10-14 at 11 02 15

To be clear. Everything works correctly in Chrome on MacOS:

Screen Shot 2022-10-15 at 09 03 31

For some reason, WordPress sets the following settings in Safari:

wp.editPost.initializeEditor( 'editor', "post", 5, {
    // ...
    "richEditingEnabled": false, // in PHP: user_can_richedit()
    "disablePostFormats": true // in PHP: ! current_theme_supports( 'post-formats' )
} );

Adding the following filter fixes it:

add_filter( 'block_editor_settings', function ( $settings, $post ) {
	$settings['richEditingEnabled'] = true;
	$settings['codeEditingEnabled'] = true;
	$settings['disablePostFormats'] = false;
		
	return $settings;
}, 10, 2);

But I'd like to understand the root cause instead of solving it with a filter.

Edit: It's probably the following code paths:

function user_can_richedit() {
	// ...
	if ( $is_safari ) {
		$wp_rich_edit = ! wp_is_mobile() || ( preg_match( '!AppleWebKit/(\d+)!', $_SERVER['HTTP_USER_AGENT'], $match ) && (int) $match[1] >= 534 );
	}
}
if ( $is_safari && stripos( $_SERVER['HTTP_USER_AGENT'], 'mobile' ) !== false ) {
	$is_iphone = true;
}

function wp_is_mobile() {
	if ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
		$is_mobile = false;
	} elseif ( strpos( $_SERVER['HTTP_USER_AGENT'], 'Mobile' ) !== false || strpos( $_SERVER['HTTP_USER_AGENT'],
			'Android' ) !== false || strpos( $_SERVER['HTTP_USER_AGENT'], 'Silk/' ) !== false || strpos( $_SERVER['HTTP_USER_AGENT'],
			'Kindle' ) !== false || strpos( $_SERVER['HTTP_USER_AGENT'], 'BlackBerry' ) !== false || strpos( $_SERVER['HTTP_USER_AGENT'],
			'Opera Mini' ) !== false || strpos( $_SERVER['HTTP_USER_AGENT'], 'Opera Mobi' ) !== false ) {
		$is_mobile = true;
	} else {
		$is_mobile = false;
	}

	return apply_filters( 'wp_is_mobile', $is_mobile );
}

Turns out $_SERVER['HTTP_USER_AGENT'] wasn't set before dispatching the PHP request. Fixed in f8e1322

Awesome. It’s a bit surprising that the logic depends so much on the detected browser, but it should now work correctly in all cases.

This is happening again as reported by @fabiankaegy. Probably it's a $_SERVER['HTTP_USER_AGENT'] regression related to switching from dispatching request with PHP code to a dedicated SAPI.

Fixed in 7a9b864