Page MenuHomePhabricator

More than one WikiEditor instance on page causes issues for CodeMirror
Closed, ResolvedPublicBUG REPORT

Description

I can't give steps to reproduce since I haven't released this to production yet, but what I do locally is:

  1. Create more than one instance of WikiEditor with CodeMirror
  2. Toggle CodeMirror in one of the instances on and off

Screen recording:

chrome_gv2oXCtZEH.gif (511×1 px, 129 KB)

Apart from multiplying search buttons in WikiEditor, after several such togglings Chrome freezes and I see in DevTools that the execution gets stuck on the line https://github.com/wikimedia/mediawiki-extensions-CodeMirror/blame/6311920da97bbce7e849fda605811944a673d92c/resources/codemirror.wikieditor.js#L225:

			// Restore original search button.
			this.$searchBtn.replaceWith( this.$oldSearchBtn );

where it cycles in a really long loop.

The cause seems to be the fact that an absolute selector is used on the line https://github.com/wikimedia/mediawiki-extensions-CodeMirror/blame/6311920da97bbce7e849fda605811944a673d92c/resources/codemirror.wikieditor.js#L188

		this.$searchBtn = $( '.wikiEditor-ui .group-search .tool' );

instead of a relative one (like this.$textarea.closest('.wikiEditor-ui').find('.group-search .tool')). It can collect more than one search button from the page which will then lead to said issues.

Please tell me If this information is not enough.

Event Timeline

Change #1186121 had a related patch set uploaded (by MusikAnimal; author: MusikAnimal):

[mediawiki/extensions/CodeMirror@master] CodeMirrorWikiEditor: query for search btn within current WE context

https://gerrit.wikimedia.org/r/1186121

MusikAnimal changed the task status from Open to In Progress.Sep 9 2025, 1:16 AM
MusikAnimal claimed this task.
MusikAnimal subscribed.

Attached patch should fix it. I'll note that for what you're trying to do, you may (or may not) want to use CodeMirrorChild instances.

Change #1186121 merged by jenkins-bot:

[mediawiki/extensions/CodeMirror@master] CodeMirrorWikiEditor: query for search btn within current WE context

https://gerrit.wikimedia.org/r/1186121

I'll note that for what you're trying to do, you may (or may not) want to use CodeMirrorChild instances.

Thanks for the guidance. But I think my users should be able to toggle CodeMirror in different editors independently (e.g. one comment has complex syntax while another hasn't).

(But I've already stumbled upon other issues with multiple CodeMirror instances: clicking <label> of preference checkboxes in the second editor checks the checkbox in the first editor since they have the same input IDs assigned in codemirror.codex.js#L121. But it also indirectly checks the checkbox in the second editor thanks to the hook in codemirror.preferences.js#L614

		// Update the checked state when the preference is changed.
		mw.hook( 'ext.CodeMirror.preferences.apply' ).add( ( pref, enabled ) => {
			if ( pref === name ) {
				input.checked = enabled;
			}
		} );

(but doesn't change the appearance of the editor!). Don't have time to create a task yet...)

MusikAnimal moved this task from Bugs to Done on the MediaWiki-extensions-CodeMirror board.

I see you've created T404117, we can discuss there about that. Closing this. Thanks for these reports!