CM6: Rework ResourceLoader modules

Documentation is at https://w.wiki/9kxt

The idea is that modules ending in `.init` imply they initialize
CodeMirror and maniuplate the DOM. The others only export classes for
use in integreations.

In doing so, 'ext.CodeMirror.v6.WikiEditor' now only exports the
CodeMirrorWikiEditor class, while 'ext.CodeMirror.v6.WikiEditor.init'
is added for use on #wpTextbox1 through action=edit.

Bug: T174811
Change-Id: Iec62ac9dc77918904bed886d2d46ccc03e0927f7
This commit is contained in:
MusikAnimal 2024-04-15 01:05:07 -04:00
parent 918b1bc295
commit c853e9587d
6 changed files with 20 additions and 9 deletions

View file

@ -259,14 +259,22 @@
"ext.CodeMirror.v6.WikiEditor": {
"dependencies": [
"ext.wikiEditor",
"ext.CodeMirror.v6.lib",
"ext.CodeMirror.v6"
],
"packageFiles": [
"dist/codemirror.wikieditor.js"
],
"messages": [
"codemirror-toggle-label"
]
},
"ext.CodeMirror.v6.WikiEditor.init": {
"dependencies": [
"ext.CodeMirror.v6.WikiEditor",
"ext.CodeMirror.v6.mode.mediawiki"
],
"packageFiles": [
"dist/codemirror.wikieditor.mediawiki.js"
],
"messages": [
"codemirror-toggle-label"
]
}
},

View file

@ -125,7 +125,7 @@ class Hooks implements
if ( $this->shouldUseV6( $out ) ) {
$out->addModules( $useWikiEditor ?
'ext.CodeMirror.v6.WikiEditor' :
'ext.CodeMirror.v6.WikiEditor.init' :
'ext.CodeMirror.v6.init'
);
} else {
@ -149,7 +149,7 @@ class Hooks implements
if ( $this->shouldUseV6( $out ) && $this->shouldLoadCodeMirror( $out ) ) {
$useWikiEditor = $this->userOptionsLookup->getBoolOption( $out->getUser(), 'usebetatoolbar' );
$out->addModules( $useWikiEditor ?
'ext.CodeMirror.v6.WikiEditor' :
'ext.CodeMirror.v6.WikiEditor.init' :
'ext.CodeMirror.v6.init'
);
}

View file

@ -0,0 +1 @@
"use strict";var e=require("ext.CodeMirror.v6.lib"),t=function(t){function r(t,i){var o;return e._classCallCheck(this,r),(o=e._callSuper(this,r,[t])).langExtension=i,o.useCodeMirror=mw.user.options.get("usecodemirror")>0,o.realtimePreviewHandler=null,o}return e._inherits(r,t),e._createClass(r,[{key:"setCodeMirrorPreference",value:function(t){this.useCodeMirror=t,e._get(e._getPrototypeOf(r.prototype),"setCodeMirrorPreference",this).call(this,t)}},{key:"enableCodeMirror",value:function(){var t=this;if(!this.view){var r=this.$textarea.prop("selectionStart"),i=this.$textarea.prop("selectionEnd"),o=this.$textarea.scrollTop(),a=this.$textarea.is(":focus"),s=[this.defaultExtensions,this.langExtension,e.EditorView.updateListener.of((function(e){e.docChanged&&"function"==typeof t.realtimePreviewHandler&&t.realtimePreviewHandler()}))];if(this.initialize(s),this.addRealtimePreviewHandler(),requestAnimationFrame((function(){t.view.scrollDOM.scrollTop=o})),0!==r||0!==i){var n=e.EditorSelection.range(r,i),d=e.EditorView.scrollIntoView(n);d.value.isSnapshot=!0,this.view.dispatch({selection:e.EditorSelection.create([n]),effects:d})}a&&this.view.focus(),mw.hook("ext.CodeMirror.switch").fire(!0,$(this.view.dom))}}},{key:"addRealtimePreviewHandler",value:function(){var e=this;mw.hook("ext.WikiEditor.realtimepreview.enable").add((function(t){e.realtimePreviewHandler=t.getEventHandler().bind(t)})),mw.hook("ext.WikiEditor.realtimepreview.disable").add((function(){e.realtimePreviewHandler=null}))}},{key:"addCodeMirrorToWikiEditor",value:function(){var e=this,t=this.$textarea.data("wikiEditor-context"),r=t&&t.modules&&t.modules.toolbar;r&&(this.$textarea.wikiEditor("addToToolbar",{section:"main",groups:{codemirror:{tools:{CodeMirror:{label:mw.msg("codemirror-toggle-label"),type:"toggle",oouiIcon:"highlight",action:{type:"callback",execute:function(){return e.switchCodeMirror()}}}}}}}),r.$toolbar.find(".tool[rel=CodeMirror]").attr("id","mw-editbutton-codemirror"),this.readOnly&&this.$textarea.data("wikiEditor-context").$ui.addClass("ext-codemirror-readonly"),this.useCodeMirror&&this.enableCodeMirror(),this.updateToolbarButton(),this.logUsage({editor:"wikitext",enabled:this.useCodeMirror,toggled:!1,edit_start_ts_ms:1e3*parseInt($('input[name="wpStarttime"]').val(),10)||0}))}},{key:"updateToolbarButton",value:function(){var e=$("#mw-editbutton-codemirror");e.toggleClass("mw-editbutton-codemirror-active",this.useCodeMirror),e.data("setActive")&&e.data("setActive")(this.useCodeMirror)}},{key:"switchCodeMirror",value:function(){this.view?(this.setCodeMirrorPreference(!1),this.destroy(),mw.hook("ext.CodeMirror.switch").fire(!1,this.$textarea)):(this.enableCodeMirror(),this.setCodeMirrorPreference(!0)),this.updateToolbarButton(),this.logUsage({editor:"wikitext",enabled:this.useCodeMirror,toggled:!0,edit_start_ts_ms:1e3*parseInt($('input[name="wpStarttime"]').val(),10)||0})}}]),r}(require("ext.CodeMirror.v6"));module.exports=t;

View file

@ -1 +1 @@
"use strict";var e=require("ext.CodeMirror.v6.lib"),t=require("ext.CodeMirror.v6"),i=require("ext.CodeMirror.v6.mode.mediawiki"),r=function(t){function i(t,r){var o;return e._classCallCheck(this,i),(o=e._callSuper(this,i,[t])).langExtension=r,o.useCodeMirror=mw.user.options.get("usecodemirror")>0,o.realtimePreviewHandler=null,o}return e._inherits(i,t),e._createClass(i,[{key:"setCodeMirrorPreference",value:function(t){this.useCodeMirror=t,e._get(e._getPrototypeOf(i.prototype),"setCodeMirrorPreference",this).call(this,t)}},{key:"enableCodeMirror",value:function(){var t=this;if(!this.view){var i=this.$textarea.prop("selectionStart"),r=this.$textarea.prop("selectionEnd"),o=this.$textarea.scrollTop(),a=this.$textarea.is(":focus"),s=[this.defaultExtensions,this.langExtension,e.EditorView.updateListener.of((function(e){e.docChanged&&"function"==typeof t.realtimePreviewHandler&&t.realtimePreviewHandler()}))];if(this.initialize(s),this.addRealtimePreviewHandler(),requestAnimationFrame((function(){t.view.scrollDOM.scrollTop=o})),0!==i||0!==r){var d=e.EditorSelection.range(i,r),n=e.EditorView.scrollIntoView(d);n.value.isSnapshot=!0,this.view.dispatch({selection:e.EditorSelection.create([d]),effects:n})}a&&this.view.focus(),mw.hook("ext.CodeMirror.switch").fire(!0,$(this.view.dom))}}},{key:"addRealtimePreviewHandler",value:function(){var e=this;mw.hook("ext.WikiEditor.realtimepreview.enable").add((function(t){e.realtimePreviewHandler=t.getEventHandler().bind(t)})),mw.hook("ext.WikiEditor.realtimepreview.disable").add((function(){e.realtimePreviewHandler=null}))}},{key:"addCodeMirrorToWikiEditor",value:function(){var e=this,t=this.$textarea.data("wikiEditor-context"),i=t&&t.modules&&t.modules.toolbar;i&&(this.$textarea.wikiEditor("addToToolbar",{section:"main",groups:{codemirror:{tools:{CodeMirror:{label:mw.msg("codemirror-toggle-label"),type:"toggle",oouiIcon:"highlight",action:{type:"callback",execute:function(){return e.switchCodeMirror()}}}}}}}),i.$toolbar.find(".tool[rel=CodeMirror]").attr("id","mw-editbutton-codemirror"),this.readOnly&&this.$textarea.data("wikiEditor-context").$ui.addClass("ext-codemirror-readonly"),this.useCodeMirror&&this.enableCodeMirror(),this.updateToolbarButton(),this.logUsage({editor:"wikitext",enabled:this.useCodeMirror,toggled:!1,edit_start_ts_ms:1e3*parseInt($('input[name="wpStarttime"]').val(),10)||0}))}},{key:"updateToolbarButton",value:function(){var e=$("#mw-editbutton-codemirror");e.toggleClass("mw-editbutton-codemirror-active",this.useCodeMirror),e.data("setActive")&&e.data("setActive")(this.useCodeMirror)}},{key:"switchCodeMirror",value:function(){this.view?(this.setCodeMirrorPreference(!1),this.destroy(),mw.hook("ext.CodeMirror.switch").fire(!1,this.$textarea)):(this.enableCodeMirror(),this.setCodeMirrorPreference(!0)),this.updateToolbarButton(),this.logUsage({editor:"wikitext",enabled:this.useCodeMirror,toggled:!0,edit_start_ts_ms:1e3*parseInt($('input[name="wpStarttime"]').val(),10)||0})}}]),i}(t),o=new URLSearchParams(window.location.search);mw.loader.getState("ext.wikiEditor")&&mw.hook("wikiEditor.toolbarReady").add((function(e){new r(e,i({bidiIsolation:"rtl"===e.attr("dir")&&o.get("cm6bidi")})).addCodeMirrorToWikiEditor()}));
"use strict";var r=require("ext.CodeMirror.v6.WikiEditor"),i=require("ext.CodeMirror.v6.mode.mediawiki");require("ext.CodeMirror.v6.lib"),require("ext.CodeMirror.v6");var e=new URLSearchParams(window.location.search);mw.loader.getState("ext.wikiEditor")&&mw.hook("wikiEditor.toolbarReady").add((function(o){new r(o,i({bidiIsolation:"rtl"===o.attr("dir")&&e.get("cm6bidi")})).addCodeMirrorToWikiEditor()}));

View file

@ -13,6 +13,7 @@ const terser = require( '@rollup/plugin-terser' );
const importAliases = {
'./vendor.js': 'ext.CodeMirror.v6.lib',
'./codemirror.js': 'ext.CodeMirror.v6',
'./codemirror.wikieditor.js': 'ext.CodeMirror.v6.WikiEditor',
'./codemirror.mode.mediawiki.js': 'ext.CodeMirror.v6.mode.mediawiki'
};
@ -23,6 +24,7 @@ module.exports = [
'src/codemirror.js',
'src/codemirror.mode.mediawiki.js',
'src/codemirror.mediawiki.js',
'src/codemirror.wikieditor.js',
'src/codemirror.wikieditor.mediawiki.js'
],

View file

@ -70,9 +70,9 @@ class HookTest extends MediaWikiIntegrationTestCase {
public static function provideOnEditPageShowEditFormInitial(): Generator {
// useCodeMirrorV6, expectedAddModuleCalls, expectedFirstModule, readOnly
yield 'CM5' => [ false, 2, 'ext.CodeMirror.WikiEditor' ];
yield 'CM6' => [ true, 1, 'ext.CodeMirror.v6.WikiEditor' ];
yield 'CM6' => [ true, 1, 'ext.CodeMirror.v6.WikiEditor.init' ];
yield 'CM5 read-only' => [ false, 0, null, true ];
yield 'CM6 read-only' => [ true, 1, 'ext.CodeMirror.v6.WikiEditor', true ];
yield 'CM6 read-only' => [ true, 1, 'ext.CodeMirror.v6.WikiEditor.init', true ];
}
/**