mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/CodeMirror
synced 2024-11-23 22:03:28 +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 ) {
|
function computeIsolates( view ) {
|
||||||
const set = new RangeSetBuilder();
|
const set = new RangeSetBuilder();
|
||||||
|
|
||||||
for ( const { from, to } of view.visibleRanges ) {
|
if ( view.editorAttrs.dir === 'rtl' ) {
|
||||||
let startPos = null;
|
for ( const { from, to } of view.visibleRanges ) {
|
||||||
syntaxTree( view.state ).iterate( {
|
let startPos = null;
|
||||||
from,
|
syntaxTree( view.state ).iterate( {
|
||||||
to,
|
from,
|
||||||
enter( node ) {
|
to,
|
||||||
// Determine if this is a bracket node (start or end of a tag).
|
enter( node ) {
|
||||||
const isBracket = node.name.split( '_' )
|
// Determine if this is a bracket node (start or end of a tag).
|
||||||
.some( ( tag ) => [
|
const isBracket = node.name.split( '_' )
|
||||||
mwModeConfig.tags.htmlTagBracket,
|
.some( ( tag ) => [
|
||||||
mwModeConfig.tags.extTagBracket
|
mwModeConfig.tags.htmlTagBracket,
|
||||||
].includes( tag ) );
|
mwModeConfig.tags.extTagBracket
|
||||||
|
].includes( tag ) );
|
||||||
|
|
||||||
if ( startPos === null && isBracket ) {
|
if ( startPos === null && isBracket ) {
|
||||||
// If we find a bracket node, we keep track of the start position.
|
// If we find a bracket node, we keep track of the start position.
|
||||||
startPos = node.from;
|
startPos = node.from;
|
||||||
} else if ( isBracket ) {
|
} else if ( isBracket ) {
|
||||||
// When we find the closing bracket, add the isolate.
|
// When we find the closing bracket, add the isolate.
|
||||||
set.add( startPos, node.to, isolate );
|
set.add( startPos, node.to, isolate );
|
||||||
startPos = null;
|
startPos = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} );
|
||||||
} );
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return set.finish();
|
return set.finish();
|
||||||
|
@ -69,6 +71,8 @@ class CodeMirrorBidiIsolation {
|
||||||
this.isolates = computeIsolates( view );
|
this.isolates = computeIsolates( view );
|
||||||
/** @type {Tree} */
|
/** @type {Tree} */
|
||||||
this.tree = syntaxTree( view.state );
|
this.tree = syntaxTree( view.state );
|
||||||
|
/** @type {Direction} */
|
||||||
|
this.dir = view.textDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,7 +80,8 @@ class CodeMirrorBidiIsolation {
|
||||||
*/
|
*/
|
||||||
update( update ) {
|
update( update ) {
|
||||||
if ( update.docChanged || update.viewportChanged ||
|
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.isolates = computeIsolates( update.view );
|
||||||
this.tree = syntaxTree( update.state );
|
this.tree = syntaxTree( update.state );
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { EditorState, Extension } from '@codemirror/state';
|
import { EditorState, Extension, Compartment } from '@codemirror/state';
|
||||||
import {
|
import {
|
||||||
EditorView,
|
EditorView,
|
||||||
drawSelection,
|
drawSelection,
|
||||||
|
@ -6,7 +6,8 @@ import {
|
||||||
highlightSpecialChars,
|
highlightSpecialChars,
|
||||||
keymap,
|
keymap,
|
||||||
rectangularSelection,
|
rectangularSelection,
|
||||||
crosshairCursor
|
crosshairCursor,
|
||||||
|
ViewUpdate
|
||||||
} from '@codemirror/view';
|
} from '@codemirror/view';
|
||||||
import { defaultKeymap, history, historyKeymap } from '@codemirror/commands';
|
import { defaultKeymap, history, historyKeymap } from '@codemirror/commands';
|
||||||
import { searchKeymap } from '@codemirror/search';
|
import { searchKeymap } from '@codemirror/search';
|
||||||
|
@ -73,6 +74,12 @@ class CodeMirror {
|
||||||
* @type {CodeMirrorTextSelection}
|
* @type {CodeMirrorTextSelection}
|
||||||
*/
|
*/
|
||||||
this.textSelection = null;
|
this.textSelection = null;
|
||||||
|
/**
|
||||||
|
* Language direction extension.
|
||||||
|
*
|
||||||
|
* @type {Compartment}
|
||||||
|
*/
|
||||||
|
this.dirCompartment = new Compartment();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,6 +98,7 @@ class CodeMirror {
|
||||||
this.heightExtension,
|
this.heightExtension,
|
||||||
this.updateExtension,
|
this.updateExtension,
|
||||||
this.bracketMatchingExtension,
|
this.bracketMatchingExtension,
|
||||||
|
this.dirExtension,
|
||||||
EditorState.readOnly.of( this.readOnly ),
|
EditorState.readOnly.of( this.readOnly ),
|
||||||
EditorView.domEventHandlers( {
|
EditorView.domEventHandlers( {
|
||||||
blur: () => this.$textarea.triggerHandler( 'blur' ),
|
blur: () => this.$textarea.triggerHandler( 'blur' ),
|
||||||
|
@ -221,9 +229,8 @@ class CodeMirror {
|
||||||
} ),
|
} ),
|
||||||
// .cm-editor element (contains the whole CodeMirror UI)
|
// .cm-editor element (contains the whole CodeMirror UI)
|
||||||
EditorView.editorAttributes.of( {
|
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)
|
// These should be attributes of .cm-editor, not the .cm-content (T359589)
|
||||||
dir: this.$textarea.attr( 'dir' ),
|
|
||||||
lang: this.$textarea.attr( 'lang' )
|
lang: this.$textarea.attr( 'lang' )
|
||||||
} ),
|
} ),
|
||||||
// The search panel should use the same direction as the interface language (T359611)
|
// 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.
|
* 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.initialize( [
|
||||||
cm.defaultExtensions,
|
cm.defaultExtensions,
|
||||||
mediaWikiLang( {
|
mediaWikiLang( {
|
||||||
bidiIsolation: textarea.dir === 'rtl' && urlParams.get( 'cm6bidi' )
|
bidiIsolation: urlParams.get( 'cm6bidi' )
|
||||||
} )
|
} )
|
||||||
] );
|
] );
|
||||||
|
|
Loading…
Reference in a new issue