diff --git a/resources/codemirror.preferences.js b/resources/codemirror.preferences.js index a2c0e1f8..e76adfbe 100644 --- a/resources/codemirror.preferences.js +++ b/resources/codemirror.preferences.js @@ -218,21 +218,10 @@ class CodeMirrorPreferences extends CodeMirrorPanel { */ get extension() { return [ - keymap.of( { - key: 'Mod-Shift-,', - run: ( view ) => { - this.view = view; - const effects = [ this.prefsToggleEffect.of( true ) ]; - if ( !this.view.state.field( this.panelStateField, false ) ) { - effects.push( StateEffect.appendConfig.of( [ this.panelStateField ] ) ); - } - this.view.dispatch( { effects } ); - this.view.dom.querySelector( - '.cm-mw-preferences-panel input:first-child' - ).focus(); - return true; - } - } ), + // Keymap for toggling the preferences panel. + keymap.of( [ + { key: 'Mod-Shift-,', run: ( view ) => this.toggle( view, true ) } + ] ), // Compartmentalized extensions Object.keys( this.extensionRegistry ).map( ( name ) => this.compartmentRegistry[ name ].of( @@ -280,17 +269,34 @@ class CodeMirrorPreferences extends CodeMirrorPanel { * Toggle display of the preferences panel. * * @param {EditorView} view - * @param {boolean} [force] + * @param {boolean} [force] Force the panel to open or close. * @return {boolean} */ toggle( view, force ) { this.view = view; - const bool = typeof force === 'boolean' ? - force : - !this.view.state.field( this.panelStateField ); - this.view.dispatch( { - effects: this.prefsToggleEffect.of( bool ) - } ); + const effects = []; + let bool; + + // Add the panel state field to the state if it doesn't exist. + if ( !this.view.state.field( this.panelStateField, false ) ) { + effects.push( StateEffect.appendConfig.of( [ this.panelStateField ] ) ); + bool = true; + } else { + bool = !this.view.state.field( this.panelStateField ); + } + if ( typeof force === 'boolean' ) { + bool = force; + } + effects.push( this.prefsToggleEffect.of( bool ) ); + this.view.dispatch( { effects } ); + + // If the panel is being opened, focus the first input. + if ( bool ) { + this.view.dom.querySelector( + '.cm-mw-preferences-panel input:first-child' + ).focus(); + } + return true; } diff --git a/resources/codemirror.wikieditor.js b/resources/codemirror.wikieditor.js index 51cd9714..232e1dfd 100644 --- a/resources/codemirror.wikieditor.js +++ b/resources/codemirror.wikieditor.js @@ -137,6 +137,35 @@ class CodeMirrorWikiEditor extends CodeMirror { } } ); + // Add a 'Settings' button to the search group of the toolbar, in the 'Advanced' section. + this.$textarea.wikiEditor( + 'addToToolbar', + { + section: 'advanced', + groups: { + search: { + tools: { + CodeMirrorPreferences: { + type: 'element', + element: () => { + const button = new OO.ui.ButtonWidget( { + title: mw.msg( 'codemirror-prefs-title' ), + icon: 'settings', + framed: false, + classes: [ 'tool', 'cm-mw-settings' ] + } ); + button.on( 'click', + () => this.preferences.toggle( this.view, true ) + ); + return button.$element; + } + } + } + } + } + } + ); + /** * Called after CodeMirror is enabled or disabled in WikiEditor. * @@ -178,6 +207,7 @@ class CodeMirrorWikiEditor extends CodeMirror { return; } + // Add 'Syntax' button to main toolbar. this.$textarea.wikiEditor( 'addToToolbar', { @@ -206,6 +236,7 @@ class CodeMirrorWikiEditor extends CodeMirror { } ); + // Set the ID of the CodeMirror button for styling. const $codeMirrorButton = toolbar.$toolbar.find( '.tool[rel=CodeMirror]' ); $codeMirrorButton.attr( 'id', 'mw-editbutton-codemirror' );