X-Git-Url: https://scripts.mit.edu/gitweb/autoinstallsdev/mediawiki.git/blobdiff_plain/19e297c21b10b1b8a3acad5e73fc71dcb35db44a..6932310fd58ebef145fa01eb76edf7150284d8ea:/resources/jquery/jquery.textSelection.js diff --git a/resources/jquery/jquery.textSelection.js b/resources/jquery/jquery.textSelection.js deleted file mode 100644 index 35e224db..00000000 --- a/resources/jquery/jquery.textSelection.js +++ /dev/null @@ -1,404 +0,0 @@ -/** - * These plugins provide extra functionality for interaction with textareas. - */ -( function( $ ) { -$.fn.textSelection = function( command, options ) { -var fn = { -/** - * Get the contents of the textarea - */ -getContents: function() { - return this.val(); -}, -/** - * Get the currently selected text in this textarea. Will focus the textarea - * in some browsers (IE/Opera) - */ -getSelection: function() { - var e = this.get( 0 ); - var retval = ''; - if ( $(e).is( ':hidden' ) ) { - // Do nothing - } else if ( document.selection && document.selection.createRange ) { - e.focus(); - var range = document.selection.createRange(); - retval = range.text; - } else if ( e.selectionStart || e.selectionStart == '0' ) { - retval = e.value.substring( e.selectionStart, e.selectionEnd ); - } - return retval; -}, -/** - * Ported from skins/common/edit.js by Trevor Parscal - * (c) 2009 Wikimedia Foundation (GPLv2) - http://www.wikimedia.org - * - * Inserts text at the begining and end of a text selection, optionally - * inserting text at the caret when selection is empty. - */ -encapsulateSelection: function( options ) { - return this.each( function() { - /** - * Check if the selected text is the same as the insert text - */ - function checkSelectedText() { - if ( !selText ) { - selText = options.peri; - isSample = true; - } else if ( options.replace ) { - selText = options.peri; - } else if ( selText.charAt( selText.length - 1 ) == ' ' ) { - // Exclude ending space char - selText = selText.substring(0, selText.length - 1); - options.post += ' '; - } - } - var isSample = false; - if ( this.style.display == 'none' ) { - // Do nothing - } else if ( this.selectionStart || this.selectionStart == '0' ) { - // Mozilla/Opera - $(this).focus(); - var selText = $(this).textSelection( 'getSelection' ); - var startPos = this.selectionStart; - var endPos = this.selectionEnd; - var scrollTop = this.scrollTop; - checkSelectedText(); - if ( options.ownline ) { - if ( startPos != 0 && this.value.charAt( startPos - 1 ) != "\n" ) { - options.pre = "\n" + options.pre; - } - if ( this.value.charAt( endPos ) != "\n" ) { - options.post += "\n"; - } - } - this.value = this.value.substring( 0, startPos ) + options.pre + selText + options.post + - this.value.substring( endPos, this.value.length ); - // Setting this.value scrolls the textarea to the top, restore the scroll position - this.scrollTop = scrollTop; - if ( window.opera ) { - options.pre = options.pre.replace( /\r?\n/g, "\r\n" ); - selText = selText.replace( /\r?\n/g, "\r\n" ); - options.post = options.post.replace( /\r?\n/g, "\r\n" ); - } - if ( isSample && options.selectPeri ) { - this.selectionStart = startPos + options.pre.length; - this.selectionEnd = startPos + options.pre.length + selText.length; - } else { - this.selectionStart = startPos + options.pre.length + selText.length + - options.post.length; - this.selectionEnd = this.selectionStart; - } - } else if ( document.selection && document.selection.createRange ) { - // IE - $(this).focus(); - if ( context ) { - context.fn.restoreCursorAndScrollTop(); - } - var selText = $(this).textSelection( 'getSelection' ); - var scrollTop = this.scrollTop; - var range = document.selection.createRange(); - if ( options.ownline && range.moveStart ) { - var range2 = document.selection.createRange(); - range2.collapse(); - range2.moveStart( 'character', -1 ); - // FIXME: Which check is correct? - if ( range2.text != "\r" && range2.text != "\n" && range2.text != "" ) { - options.pre = "\n" + options.pre; - } - var range3 = document.selection.createRange(); - range3.collapse( false ); - range3.moveEnd( 'character', 1 ); - if ( range3.text != "\r" && range3.text != "\n" && range3.text != "" ) { - options.post += "\n"; - } - } - checkSelectedText(); - range.text = options.pre + selText + options.post; - if ( isSample && options.selectPeri && range.moveStart ) { - range.moveStart( 'character', - options.post.length - selText.length ); - range.moveEnd( 'character', - options.post.length ); - } - range.select(); - // Restore the scroll position - this.scrollTop = scrollTop; - } - $(this).trigger( 'encapsulateSelection', [ options.pre, options.peri, options.post, options.ownline, - options.replace ] ); - }); -}, -/** - * Ported from Wikia's LinkSuggest extension - * https://svn.wikia-code.com/wikia/trunk/extensions/wikia/LinkSuggest - * Some code copied from - * http://www.dedestruct.com/2008/03/22/howto-cross-browser-cursor-position-in-textareas/ - * - * Get the position (in resolution of bytes not nessecarily characters) - * in a textarea - */ - getCaretPosition: function( options ) { - function getCaret( e ) { - var caretPos = 0, endPos = 0; - if ( $.browser.msie ) { - // IE Support - var preFinished = false; - var periFinished = false; - var postFinished = false; - var preText, rawPreText, periText; - var rawPeriText, postText, rawPostText; - // Create range containing text in the selection - var periRange = document.selection.createRange().duplicate(); - // Create range containing text before the selection - var preRange = document.body.createTextRange(); - // Select all the text - preRange.moveToElementText(e); - // Move the end where we need it - preRange.setEndPoint("EndToStart", periRange); - // Create range containing text after the selection - var postRange = document.body.createTextRange(); - // Select all the text - postRange.moveToElementText(e); - // Move the start where we need it - postRange.setEndPoint("StartToEnd", periRange); - // Load the text values we need to compare - preText = rawPreText = preRange.text; - periText = rawPeriText = periRange.text; - postText = rawPostText = postRange.text; - /* - * Check each range for trimmed newlines by shrinking the range by 1 - * character and seeing if the text property has changed. If it has - * not changed then we know that IE has trimmed a \r\n from the end. - */ - do { - if ( !preFinished ) { - if ( preRange.compareEndPoints( "StartToEnd", preRange ) == 0 ) { - preFinished = true; - } else { - preRange.moveEnd( "character", -1 ); - if ( preRange.text == preText ) { - rawPreText += "\r\n"; - } else { - preFinished = true; - } - } - } - if ( !periFinished ) { - if ( periRange.compareEndPoints( "StartToEnd", periRange ) == 0 ) { - periFinished = true; - } else { - periRange.moveEnd( "character", -1 ); - if ( periRange.text == periText ) { - rawPeriText += "\r\n"; - } else { - periFinished = true; - } - } - } - if ( !postFinished ) { - if ( postRange.compareEndPoints("StartToEnd", postRange) == 0 ) { - postFinished = true; - } else { - postRange.moveEnd( "character", -1 ); - if ( postRange.text == postText ) { - rawPostText += "\r\n"; - } else { - postFinished = true; - } - } - } - } while ( ( !preFinished || !periFinished || !postFinished ) ); - caretPos = rawPreText.replace( /\r\n/g, "\n" ).length; - endPos = caretPos + rawPeriText.replace( /\r\n/g, "\n" ).length; - } else if ( e.selectionStart || e.selectionStart == '0' ) { - // Firefox support - caretPos = e.selectionStart; - endPos = e.selectionEnd; - } - return options.startAndEnd ? [ caretPos, endPos ] : caretPos; - } - return getCaret( this.get( 0 ) ); -}, -setSelection: function( options ) { - return this.each( function() { - if ( $(this).is( ':hidden' ) ) { - // Do nothing - } else if ( this.selectionStart || this.selectionStart == '0' ) { - // Opera 9.0 doesn't allow setting selectionStart past - // selectionEnd; any attempts to do that will be ignored - // Make sure to set them in the right order - if ( options.start > this.selectionEnd ) { - this.selectionEnd = options.end; - this.selectionStart = options.start; - } else { - this.selectionStart = options.start; - this.selectionEnd = options.end; - } - } else if ( document.body.createTextRange ) { - var selection = document.body.createTextRange(); - selection.moveToElementText( this ); - var length = this.value.length; - // IE doesn't count \n when computing the offset, so we won't either - var newLines = this.value.match( /\n/g ); - if ( newLines) length = length - newLines.length; - selection.moveStart( 'character', options.start ); - selection.moveEnd( 'character', -length + options.end ); - - // This line can cause an error under certain circumstances (textarea empty, no selection) - // Silence that error - try { - selection.select(); - } catch( e ) { } - } - }); -}, -/** - * Ported from Wikia's LinkSuggest extension - * https://svn.wikia-code.com/wikia/trunk/extensions/wikia/LinkSuggest - * - * Scroll a textarea to the current cursor position. You can set the cursor - * position with setSelection() - * @param options boolean Whether to force a scroll even if the caret position - * is already visible. Defaults to false - */ -scrollToCaretPosition: function( options ) { - function getLineLength( e ) { - return Math.floor( e.scrollWidth / ( $.client.profile().platform == 'linux' ? 7 : 8 ) ); - } - function getCaretScrollPosition( e ) { - // FIXME: This functions sucks and is off by a few lines most - // of the time. It should be replaced by something decent. - var text = e.value.replace( /\r/g, "" ); - var caret = $( e ).textSelection( 'getCaretPosition' ); - var lineLength = getLineLength( e ); - var row = 0; - var charInLine = 0; - var lastSpaceInLine = 0; - for ( i = 0; i < caret; i++ ) { - charInLine++; - if ( text.charAt( i ) == " " ) { - lastSpaceInLine = charInLine; - } else if ( text.charAt( i ) == "\n" ) { - lastSpaceInLine = 0; - charInLine = 0; - row++; - } - if ( charInLine > lineLength ) { - if ( lastSpaceInLine > 0 ) { - charInLine = charInLine - lastSpaceInLine; - lastSpaceInLine = 0; - row++; - } - } - } - var nextSpace = 0; - for ( j = caret; j < caret + lineLength; j++ ) { - if ( - text.charAt( j ) == " " || - text.charAt( j ) == "\n" || - caret == text.length - ) { - nextSpace = j; - break; - } - } - if ( nextSpace > lineLength && caret <= lineLength ) { - charInLine = caret - lastSpaceInLine; - row++; - } - return ( $.client.profile().platform == 'mac' ? 13 : ( $.client.profile().platform == 'linux' ? 15 : 16 ) ) * row; - } - return this.each(function() { - if ( $(this).is( ':hidden' ) ) { - // Do nothing - } else if ( this.selectionStart || this.selectionStart == '0' ) { - // Mozilla - var scroll = getCaretScrollPosition( this ); - if ( options.force || scroll < $(this).scrollTop() || - scroll > $(this).scrollTop() + $(this).height() ) - $(this).scrollTop( scroll ); - } else if ( document.selection && document.selection.createRange ) { - // IE / Opera - /* - * IE automatically scrolls the selected text to the - * bottom of the textarea at range.select() time, except - * if it was already in view and the cursor position - * wasn't changed, in which case it does nothing. To - * cover that case, we'll force it to act by moving one - * character back and forth. - */ - var range = document.body.createTextRange(); - var savedRange = document.selection.createRange(); - var pos = $(this).textSelection( 'getCaretPosition' ); - var oldScrollTop = this.scrollTop; - range.moveToElementText( this ); - range.collapse(); - range.move( 'character', pos + 1); - range.select(); - if ( this.scrollTop != oldScrollTop ) - this.scrollTop += range.offsetTop; - else if ( options.force ) { - range.move( 'character', -1 ); - range.select(); - } - savedRange.select(); - } - $(this).trigger( 'scrollToPosition' ); - } ); -} -}; - // Apply defaults - 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) - }, options ); - break; - case 'getCaretPosition': - options = $.extend( { - 'startAndEnd': false // Return [start, end] instead of just start - }, options ); - // FIXME: We may not need character position-based functions if we insert markers in the right places - break; - case 'setSelection': - options = $.extend( { - 'start': undefined, // Position to start selection at - 'end': undefined, // Position to end selection at. Defaults to start - 'startContainer': undefined, // Element to start selection in (iframe only) - 'endContainer': undefined // Element to end selection in (iframe only). Defaults to startContainer - }, 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; - } - var context = $(this).data( 'wikiEditor-context' ); - var hasIframe = typeof context !== 'undefined' && context && typeof context.$iframe !== 'undefined'; - - // IE selection restore voodoo - var needSave = false; - if ( hasIframe && context.savedSelection !== null ) { - context.fn.restoreSelection(); - needSave = true; - } - retval = ( hasIframe ? context.fn : fn )[command].call( this, options ); - if ( hasIframe && needSave ) { - context.fn.saveSelection(); - } - return retval; -}; - -} )( jQuery );