Esanders has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/405748 )
Change subject: Simplify textSelection overrides using 'register' and
'unregister'
......................................................................
Simplify textSelection overrides using 'register' and 'unregister'
Change-Id: I46ac070ca141c3c2f993bee6ab898c96cb1edd4f
---
M resources/ext.CodeMirror.js
1 file changed, 106 insertions(+), 215 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/CodeMirror
refs/changes/48/405748/1
diff --git a/resources/ext.CodeMirror.js b/resources/ext.CodeMirror.js
index 3903755..0346cc8 100644
--- a/resources/ext.CodeMirror.js
+++ b/resources/ext.CodeMirror.js
@@ -1,6 +1,6 @@
( function ( mw, $ ) {
- var origTextSelection, useCodeMirror, codeMirror, api,
originHooksTextarea,
- wikiEditorToolbarEnabled, textBox,
+ var useCodeMirror, codeMirror, api, originHooksTextarea,
+ wikiEditorToolbarEnabled, cmTextSelection,
enableContentEditable = true;
if ( mw.config.get( 'wgCodeEditorCurrentLanguage' ) ) { // If the
CodeEditor is used then just exit;
@@ -16,10 +16,6 @@
if ( !wikiEditorToolbarEnabled && !mw.loader.getState(
'mediawiki.toolbar' ) ) {
return;
}
-
- // codeMirror needs a special textselection jQuery function to work,
save the current one to restore when
- // CodeMirror get's disabled.
- origTextSelection = $.fn.textSelection;
useCodeMirror = mw.user.options.get( 'usecodemirror' ) > 0;
api = new mw.Api();
@@ -56,229 +52,126 @@
CodeMirror.keyMap.pcDefault[ 'Alt-Left' ] = false;
CodeMirror.keyMap.pcDefault[ 'Alt-Right' ] = false;
- // function for a textselection function for CodeMirror
- function cmTextSelection( command, options ) {
- var fn, retval;
+ // jQuery.textSelection overrides for CodeMirror.
+ // See jQuery.textSelection.js for method documentation
+ cmTextSelection = {
+ getContents: function () {
+ return codeMirror.doc.getValue();
+ },
+ setContents: function ( content ) {
+ codeMirror.doc.setValue( content );
+ },
+ getSelection: function () {
+ return codeMirror.doc.getSelection();
+ },
+ setSelection: function ( options ) {
+ return this.each( function () {
+ codeMirror.doc.setSelection(
codeMirror.doc.posFromIndex( options.start ), codeMirror.doc.posFromIndex(
options.end ) );
+ codeMirror.focus();
+ } );
+ },
+ encapsulateSelection: function ( options ) {
+ return this.each( function () {
+ var insertText,
+ selText,
+ selectPeri = options.selectPeri,
+ pre = options.pre,
+ post = options.post,
+ startCursor = codeMirror.doc.getCursor(
true ),
+ endCursor = codeMirror.doc.getCursor(
false );
- if ( !codeMirror ||
- ( this[ 0 ] !== textBox && this[ 0 ] !==
codeMirror.getWrapperElement() )
- ) {
- return origTextSelection.call( this, command, options );
- }
+ if ( options.selectionStart !== undefined ) {
+ // fn[command].call( this, options );
+ cmTextSelection.setSelection.call( $(
this ), { start: options.selectionStart, end: options.selectionEnd } ); // not
tested
+ }
- fn = {
- /**
- * Get the contents of the textarea
- *
- * @return {string}
- */
- getContents: function () {
- return codeMirror.doc.getValue();
- },
-
- setContents: function ( newContents ) {
- codeMirror.doc.setValue( newContents );
- },
-
- /**
- * Get the currently selected text in this textarea.
Will focus the textarea
- * in some browsers (IE/Opera)
- *
- * @return {string}
- */
- getSelection: function () {
- return codeMirror.doc.getSelection();
- },
-
- /**
- * Inserts text at the beginning and end of a text
selection, optionally
- * inserting text at the caret when selection is empty.
- *
- * @param {Object} options
- * @return {jQuery}
- */
- encapsulateSelection: function ( options ) {
- return this.each( function () {
- var insertText,
- selText,
- selectPeri = options.selectPeri,
- pre = options.pre,
- post = options.post,
- startCursor =
codeMirror.doc.getCursor( true ),
- endCursor =
codeMirror.doc.getCursor( false );
-
- if ( options.selectionStart !==
undefined ) {
- // fn[command].call( this,
options );
- fn.setSelection( { start:
options.selectionStart, end: options.selectionEnd } ); // not tested
+ selText = codeMirror.doc.getSelection();
+ if ( !selText ) {
+ selText = options.peri;
+ } else if ( options.replace ) {
+ selectPeri = false;
+ selText = options.peri;
+ } else {
+ selectPeri = false;
+ while ( selText.charAt( selText.length
- 1 ) === ' ' ) {
+ // Exclude ending space char
+ selText = selText.substring( 0,
selText.length - 1 );
+ post += ' ';
}
-
- selText = codeMirror.doc.getSelection();
- if ( !selText ) {
- selText = options.peri;
- } else if ( options.replace ) {
- selectPeri = false;
- selText = options.peri;
- } else {
- selectPeri = false;
- while ( selText.charAt(
selText.length - 1 ) === ' ' ) {
- // Exclude ending space
char
- selText =
selText.substring( 0, selText.length - 1 );
- post += ' ';
- }
- while ( selText.charAt( 0 ) ===
' ' ) {
- // Exclude prepending
space char
- selText =
selText.substring( 1, selText.length );
- pre = ' ' + pre;
- }
+ while ( selText.charAt( 0 ) === ' ' ) {
+ // Exclude prepending space char
+ selText = selText.substring( 1,
selText.length );
+ pre = ' ' + pre;
}
+ }
- /**
- * Do the splitlines stuff.
- *
- * Wrap each line of the selected text
with pre and post
- *
- * @param {string} selText
- * @param {string} pre
- * @param {string} post
- * @return {string}
- */
- function doSplitLines( selText, pre,
post ) {
- var i,
- insertText = '',
- selTextArr =
selText.split( '\n' );
+ /**
+ * Do the splitlines stuff.
+ *
+ * Wrap each line of the selected text with pre
and post
+ *
+ * @param {string} selText
+ * @param {string} pre
+ * @param {string} post
+ * @return {string}
+ */
+ function doSplitLines( selText, pre, post ) {
+ var i,
+ insertText = '',
+ selTextArr = selText.split(
'\n' );
- for ( i = 0; i <
selTextArr.length; i++ ) {
- insertText += pre +
selTextArr[ i ] + post;
- if ( i !==
selTextArr.length - 1 ) {
- insertText +=
'\n';
- }
- }
- return insertText;
- }
-
- if ( options.splitlines ) {
- selectPeri = false;
- insertText = doSplitLines(
selText, pre, post );
- } else {
- insertText = pre + selText +
post;
- }
-
- if ( options.ownline ) {
- if ( startCursor.ch !== 0 ) {
- insertText = '\n' +
insertText;
- pre += '\n';
- }
-
- if ( codeMirror.doc.getLine(
endCursor.line ).length !== endCursor.ch ) {
+ for ( i = 0; i < selTextArr.length; i++
) {
+ insertText += pre + selTextArr[
i ] + post;
+ if ( i !== selTextArr.length -
1 ) {
insertText += '\n';
- post += '\n';
}
}
+ return insertText;
+ }
- codeMirror.doc.replaceSelection(
insertText );
+ if ( options.splitlines ) {
+ selectPeri = false;
+ insertText = doSplitLines( selText,
pre, post );
+ } else {
+ insertText = pre + selText + post;
+ }
- if ( selectPeri ) {
- codeMirror.doc.setSelection(
-
codeMirror.doc.posFromIndex( codeMirror.doc.indexFromPos( startCursor ) +
pre.length ),
-
codeMirror.doc.posFromIndex( codeMirror.doc.indexFromPos( startCursor ) +
pre.length + selText.length )
- );
+ if ( options.ownline ) {
+ if ( startCursor.ch !== 0 ) {
+ insertText = '\n' + insertText;
+ pre += '\n';
}
- } );
- },
- /**
- * Get the position (in resolution of bytes not
necessarily characters)
- * in a textarea
- *
- * @param {Object} options
- * @return {number}
- */
- getCaretPosition: function ( options ) {
- var caretPos = codeMirror.doc.indexFromPos(
codeMirror.doc.getCursor( true ) ),
- endPos = codeMirror.doc.indexFromPos(
codeMirror.doc.getCursor( false ) );
- if ( options.startAndEnd ) {
- return [ caretPos, endPos ];
+ if ( codeMirror.doc.getLine(
endCursor.line ).length !== endCursor.ch ) {
+ insertText += '\n';
+ post += '\n';
+ }
}
- return caretPos;
- },
- setSelection: function ( options ) {
- return this.each( function () {
- codeMirror.doc.setSelection(
codeMirror.doc.posFromIndex( options.start ), codeMirror.doc.posFromIndex(
options.end ) );
- } );
- },
+ codeMirror.doc.replaceSelection( insertText );
- /**
- * Scroll a textarea to the current cursor position. You
can set the cursor
- * position with setSelection()
- *
- * @return {jQuery}
- */
- scrollToCaretPosition: function () {
- return this.each( function () {
- codeMirror.scrollIntoView( null );
- } );
+ if ( selectPeri ) {
+ codeMirror.doc.setSelection(
+ codeMirror.doc.posFromIndex(
codeMirror.doc.indexFromPos( startCursor ) + pre.length ),
+ codeMirror.doc.posFromIndex(
codeMirror.doc.indexFromPos( startCursor ) + pre.length + selText.length )
+ );
+ }
+ } );
+ },
+ getCaretPosition: function ( options ) {
+ var caretPos = codeMirror.doc.indexFromPos(
codeMirror.doc.getCursor( true ) ),
+ endPos = codeMirror.doc.indexFromPos(
codeMirror.doc.getCursor( false ) );
+ if ( options.startAndEnd ) {
+ return [ caretPos, endPos ];
}
- };
-
- switch ( command ) {
- // case 'getContents': // no params
- // case 'setContents': // no params with defaults
- // case 'getSelection': // no params
- case 'encapsulateSelection':
- options = $.extend( {
- pre: '', // Text to insert before the
cursor/selection
- peri: '', // Text to insert between pre
and post and select afterwards
- post: '', // Text to insert after the
cursor/selection
- ownline: false, // Put the inserted
text on a line of its own
- replace: false, // If there is a
selection, replace it with peri instead of leaving it alone
- selectPeri: true, // Select the peri
text if it was inserted (but not if there was a selection and replace==false,
or if splitlines==true)
- splitlines: false, // If multiple lines
are selected, encapsulate each line individually
- selectionStart: undefined, // Position
to start selection at
- selectionEnd: undefined // Position to
end selection at. Defaults to start
- }, options );
- break;
- case 'getCaretPosition':
- options = $.extend( {
- // Return [start, end] instead of just
start
- startAndEnd: false
- }, options );
- // FIXME: We may not need character
position-based functions if we insert markers in the right places
- break;
- case 'setSelection':
- options = $.extend( {
- // Position to start selection at
- start: undefined,
- // Position to end selection at.
Defaults to start
- end: undefined,
- // Element to start selection in
(iframe only)
- startContainer: undefined,
- // Element to end selection in (iframe
only). Defaults to startContainer
- endContainer: undefined
- }, options );
-
- if ( options.end === undefined ) {
- options.end = options.start;
- }
- if ( options.endContainer === undefined ) {
- options.endContainer =
options.startContainer;
- }
- // FIXME: We may not need character
position-based functions if we insert markers in the right places
- break;
- case 'scrollToCaretPosition':
- options = $.extend( {
- force: false // Force a scroll even if
the caret position is already visible
- }, options );
- break;
+ return caretPos;
+ },
+ scrollToCaretPosition: function () {
+ return this.each( function () {
+ codeMirror.scrollIntoView( null );
+ } );
}
-
- retval = fn[ command ].call( this, options );
- if ( command === 'setSelection' ) {
- codeMirror.focus();
- }
-
- return retval;
- }
+ };
/**
* Save CodeMirror enabled pref.
@@ -333,7 +226,7 @@
} );
$codeMirror = $( codeMirror.getWrapperElement() );
- textBox = $textbox1[ 0 ];
+ $textbox1.textSelection( 'register', cmTextSelection );
$codeMirror.resizable( {
handles: 'se',
@@ -363,8 +256,6 @@
// set the height of the textarea
codeMirror.setSize( null, $textbox1.height() );
- // Overwrite default textselection of WikiEditor to
work with CodeMirror, too
- $.fn.textSelection = cmTextSelection;
} );
}
@@ -397,7 +288,7 @@
setCodeEditorPreference( false );
codeMirror.toTextArea();
codeMirror = null;
- $.fn.textSelection = origTextSelection;
+ $textbox1.textSelection( 'unregister' );
if ( hasFocus ) {
$textbox1.focus();
}
--
To view, visit https://gerrit.wikimedia.org/r/405748
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I46ac070ca141c3c2f993bee6ab898c96cb1edd4f
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/CodeMirror
Gerrit-Branch: master
Gerrit-Owner: Esanders <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits