mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/CodeMirror
synced 2024-11-23 13:56:44 +00:00
codemirror.mediawiki.js: add Mod-Shift-x
This patch adds a keyboard shortcut `Mod-Shift-x` to toggle between left-to-right (LTR) and right-to-left (RTL) text directions. Bug: T170001 Change-Id: Ia857ad0b0aff0bb206b45e4d27dee6e91a3effce
This commit is contained in:
parent
999382fd16
commit
0e0e4927ab
2
resources/dist/codemirror.js
vendored
2
resources/dist/codemirror.js
vendored
File diff suppressed because one or more lines are too long
2
resources/dist/codemirror.mediawiki.js
vendored
2
resources/dist/codemirror.mediawiki.js
vendored
|
@ -1 +1 @@
|
|||
"use strict";var e=require("ext.CodeMirror.v6"),i=require("ext.CodeMirror.v6.mode.mediawiki");require("ext.CodeMirror.v6.lib");var r=document.getElementById("wpTextbox1"),o=new e(r),t=new URLSearchParams(window.location.search);o.initialize([o.defaultExtensions,i({bidiIsolation:"rtl"===r.dir&&t.get("cm6bidi")})]);
|
||||
"use strict";var e=require("ext.CodeMirror.v6"),i=require("ext.CodeMirror.v6.mode.mediawiki");require("ext.CodeMirror.v6.lib");var r=new e(document.getElementById("wpTextbox1")),o=new URLSearchParams(window.location.search);r.initialize([r.defaultExtensions,i({bidiIsolation:o.get("cm6bidi")})]);
|
||||
|
|
2
resources/dist/codemirror.mode.mediawiki.js
vendored
2
resources/dist/codemirror.mode.mediawiki.js
vendored
File diff suppressed because one or more lines are too long
2
resources/dist/vendor.js
vendored
2
resources/dist/vendor.js
vendored
File diff suppressed because one or more lines are too long
|
@ -28,29 +28,31 @@ const isolate = Decoration.mark( {
|
|||
function computeIsolates( view ) {
|
||||
const set = new RangeSetBuilder();
|
||||
|
||||
for ( const { from, to } of view.visibleRanges ) {
|
||||
let startPos = null;
|
||||
syntaxTree( view.state ).iterate( {
|
||||
from,
|
||||
to,
|
||||
enter( node ) {
|
||||
// Determine if this is a bracket node (start or end of a tag).
|
||||
const isBracket = node.name.split( '_' )
|
||||
.some( ( tag ) => [
|
||||
mwModeConfig.tags.htmlTagBracket,
|
||||
mwModeConfig.tags.extTagBracket
|
||||
].includes( tag ) );
|
||||
if ( view.editorAttrs.dir === 'rtl' ) {
|
||||
for ( const { from, to } of view.visibleRanges ) {
|
||||
let startPos = null;
|
||||
syntaxTree( view.state ).iterate( {
|
||||
from,
|
||||
to,
|
||||
enter( node ) {
|
||||
// Determine if this is a bracket node (start or end of a tag).
|
||||
const isBracket = node.name.split( '_' )
|
||||
.some( ( tag ) => [
|
||||
mwModeConfig.tags.htmlTagBracket,
|
||||
mwModeConfig.tags.extTagBracket
|
||||
].includes( tag ) );
|
||||
|
||||
if ( startPos === null && isBracket ) {
|
||||
// If we find a bracket node, we keep track of the start position.
|
||||
startPos = node.from;
|
||||
} else if ( isBracket ) {
|
||||
// When we find the closing bracket, add the isolate.
|
||||
set.add( startPos, node.to, isolate );
|
||||
startPos = null;
|
||||
if ( startPos === null && isBracket ) {
|
||||
// If we find a bracket node, we keep track of the start position.
|
||||
startPos = node.from;
|
||||
} else if ( isBracket ) {
|
||||
// When we find the closing bracket, add the isolate.
|
||||
set.add( startPos, node.to, isolate );
|
||||
startPos = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
return set.finish();
|
||||
|
@ -69,6 +71,8 @@ class CodeMirrorBidiIsolation {
|
|||
this.isolates = computeIsolates( view );
|
||||
/** @type {Tree} */
|
||||
this.tree = syntaxTree( view.state );
|
||||
/** @type {Direction} */
|
||||
this.dir = view.textDirection;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,7 +80,8 @@ class CodeMirrorBidiIsolation {
|
|||
*/
|
||||
update( update ) {
|
||||
if ( update.docChanged || update.viewportChanged ||
|
||||
syntaxTree( update.state ) !== this.tree
|
||||
syntaxTree( update.state ) !== this.tree ||
|
||||
update.view.textDirection !== this.dir
|
||||
) {
|
||||
this.isolates = computeIsolates( update.view );
|
||||
this.tree = syntaxTree( update.state );
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { EditorState, Extension } from '@codemirror/state';
|
||||
import { EditorState, Extension, Compartment } from '@codemirror/state';
|
||||
import {
|
||||
EditorView,
|
||||
drawSelection,
|
||||
|
@ -6,7 +6,8 @@ import {
|
|||
highlightSpecialChars,
|
||||
keymap,
|
||||
rectangularSelection,
|
||||
crosshairCursor
|
||||
crosshairCursor,
|
||||
ViewUpdate
|
||||
} from '@codemirror/view';
|
||||
import { defaultKeymap, history, historyKeymap } from '@codemirror/commands';
|
||||
import { searchKeymap } from '@codemirror/search';
|
||||
|
@ -73,6 +74,12 @@ class CodeMirror {
|
|||
* @type {CodeMirrorTextSelection}
|
||||
*/
|
||||
this.textSelection = null;
|
||||
/**
|
||||
* Language direction extension.
|
||||
*
|
||||
* @type {Compartment}
|
||||
*/
|
||||
this.dirCompartment = new Compartment();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,6 +98,7 @@ class CodeMirror {
|
|||
this.heightExtension,
|
||||
this.updateExtension,
|
||||
this.bracketMatchingExtension,
|
||||
this.dirExtension,
|
||||
EditorState.readOnly.of( this.readOnly ),
|
||||
EditorView.domEventHandlers( {
|
||||
blur: () => this.$textarea.triggerHandler( 'blur' ),
|
||||
|
@ -221,9 +229,8 @@ class CodeMirror {
|
|||
} ),
|
||||
// .cm-editor element (contains the whole CodeMirror UI)
|
||||
EditorView.editorAttributes.of( {
|
||||
// Use direction and language of the original textbox.
|
||||
// Use language of the original textbox.
|
||||
// These should be attributes of .cm-editor, not the .cm-content (T359589)
|
||||
dir: this.$textarea.attr( 'dir' ),
|
||||
lang: this.$textarea.attr( 'lang' )
|
||||
} ),
|
||||
// The search panel should use the same direction as the interface language (T359611)
|
||||
|
@ -321,6 +328,29 @@ class CodeMirror {
|
|||
} );
|
||||
}
|
||||
|
||||
get dirExtension() {
|
||||
return [
|
||||
this.dirCompartment.of( EditorView.editorAttributes.of( {
|
||||
// Use direction of the original textbox.
|
||||
// These should be attributes of .cm-editor, not the .cm-content (T359589)
|
||||
dir: this.$textarea.attr( 'dir' )
|
||||
} ) ),
|
||||
keymap.of( [ {
|
||||
key: 'Mod-Shift-x',
|
||||
run: ( view ) => {
|
||||
const dir = this.$textarea.attr( 'dir' ) === 'rtl' ? 'ltr' : 'rtl';
|
||||
this.$textarea.attr( 'dir', dir );
|
||||
view.dispatch( {
|
||||
effects: this.dirCompartment.reconfigure(
|
||||
EditorView.editorAttributes.of( { dir } )
|
||||
)
|
||||
} );
|
||||
return true;
|
||||
}
|
||||
} ] )
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup CodeMirror and add it to the DOM. This will hide the original textarea.
|
||||
*
|
||||
|
|
|
@ -8,6 +8,6 @@ const urlParams = new URLSearchParams( window.location.search );
|
|||
cm.initialize( [
|
||||
cm.defaultExtensions,
|
||||
mediaWikiLang( {
|
||||
bidiIsolation: textarea.dir === 'rtl' && urlParams.get( 'cm6bidi' )
|
||||
bidiIsolation: urlParams.get( 'cm6bidi' )
|
||||
} )
|
||||
] );
|
||||
|
|
Loading…
Reference in a new issue