WordPress.org

Make WordPress Core

Opened 2 years ago

Closed 2 years ago

#41900 closed defect (bug) (fixed)

Code Editor: Cursor jumps to end of file upon focus in the "contenteditable" inputStyle for CodeMirror in Additional CSS

Reported by: westonruter Owned by: westonruter
Milestone: 4.9 Priority: high
Severity: normal Version:
Component: Customize Keywords: needs-patch
Focuses: accessibility Cc:

Description (last modified by westonruter)

In the editor which appears in the Customizer for the Additional CSS feature, when you click on the editor to focus and set the cursor on a given line, it will focus but then put the cursor at the end of the editor without scrolling to that position. Sometimes it will even add the active-line style to where you clicked, but the cursor is at the bottom. Every time you blur the editor an then focus back into the editor, the cursor will get moved to the end of the file.

Of note, this issue can be observed exclusively in the editor for Additional CSS in the Customizer. It is not present on the theme/plugin editors. It is not even present for the code editor in the Custom HTML widget in the Customizer either. There seems to be something specifically about the Additional CSS editor.

This issue appears when CodeMirror is configured with a 'contenteditable' inputStyle, which it is by default in core for the sake of a11y. Per the CodeMirror docs on inputStyle:

Selects the way CodeMirror handles input and focus. The core library defines the "textarea" and "contenteditable" input models. On mobile browsers, the default is "contenteditable". On desktop browsers, the default is "textarea". Support for IME and screen readers is better in the "contenteditable" model. The intention is to make it the default on modern desktop browsers in the future.

If the inputStyle is changed from 'contenteditable' to 'textarea' then the issue goes away. This change:

  • src/wp-includes/general-template.php

    function wp_enqueue_code_editor( $args ) { 
    31423142                'codemirror' => array(
    31433143                        'indentUnit' => 4,
    31443144                        'indentWithTabs' => true,
    3145                         'inputStyle' => 'contenteditable',
     3145                        'inputStyle' => 'textarea',
    31463146                        'lineNumbers' => true,
    31473147                        'lineWrapping' => true,
    31483148                        'styleActiveLine' => true,

However, since the inputSyle of 'contenteditable' improves accessibility, I'm wary to make this change.

Videos that depict the issue with the contenteditable inputStyle and how it is not present for the textarea inputStyle:

FAIL (inputStyle=contenteditable): https://youtu.be/uSFJqf_zwFw
PASS (inputStyle=textarea): https://youtu.be/CqMLObojkVU

Change History (8)

#1 @westonruter
2 years ago

  • Description modified (diff)
  • Summary changed from Code Editor: Cursor jumps to end of file upon focus in the "contenteditable" inputStyle for CodeMirror to Code Editor: Cursor jumps to end of file upon focus in the "contenteditable" inputStyle for CodeMirror in Additional CSS

#2 @westonruter
2 years ago

  • Description modified (diff)

#3 @westonruter
2 years ago

  • Description modified (diff)

#4 @westonruter
2 years ago

  • Component changed from General to Customize

#6 @westonruter
2 years ago

  • Priority changed from normal to high

Bumping priority to high for visibility and alignment with 4.9 goals, and given proximity to beta 1 deadline.

#7 @westonruter
2 years ago

  • Keywords needs-patch added
  • Owner set to westonruter
  • Status changed from new to accepted

I believe the cause has been identified by @afercia in #41872:

When clicking on the label it should focus on the CodeMirror editor.

Trying this on the Additional CSS, focus always goes to the last line (and if the content is very long, it's out of view). Seems to me because of:

			// Refresh when receiving focus.
			control.editor.codemirror.on( 'focus', function( codemirror ) {
				codemirror.refresh();
			});

Is this really necessary? And why it is used only for the Additional CSS and not for the other CodeMirror instances? If there are no particular reasons, I'd consider to remove it.

I do think actually that codemirror.refresh() is obsolete because we are already ensuring the textarea is synced.

#8 @westonruter
2 years ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 41582:

Customize: Remove unnecessary call to refresh() a CodeMirror instance upon focus in Code Editor control.

This also fixes an issue with the cursor not being set in the expected location with an inputStyle=contenteditable.

Props afercia.
See #41897.
Fixes #41900.

Note: See TracTickets for help on using tickets.