X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=resources%2Fjquery%2Fjquery.textSelection.js;h=17fd0cd35fd0c4ae242c5aac9a80d9ce033223d1;hb=586596f19f0ca03ab0d940bdcd7b61575c851130;hp=9f1f3a4f3ca8e384c4b0c48c7e080697bbfb45ba;hpb=7ab935b039e67242b8607335b78f4e85c0eaed0d;p=lhc%2Fweb%2Fwiklou.git diff --git a/resources/jquery/jquery.textSelection.js b/resources/jquery/jquery.textSelection.js index 9f1f3a4f3c..17fd0cd35f 100644 --- a/resources/jquery/jquery.textSelection.js +++ b/resources/jquery/jquery.textSelection.js @@ -8,22 +8,28 @@ // On IE, patch the focus() method to restore the windows' scroll position // (bug 32241) $.fn.extend({ - focus : ( function ( _focus ) { + focus: ( function ( jqFocus ) { return function () { + var $w, state, result; if ( arguments.length === 0 ) { - var $w = $( window ); - var state = {top: $w.scrollTop(), left: $w.scrollLeft()}; - var result = _focus.apply( this, arguments ); + $w = $( window ); + state = {top: $w.scrollTop(), left: $w.scrollLeft()}; + result = jqFocus.apply( this, arguments ); window.scrollTo( state.top, state.left ); return result; } - return _focus.apply( this, arguments ); + return jqFocus.apply( this, arguments ); }; }( $.fn.focus ) ) }); } $.fn.textSelection = function ( command, options ) { + var fn, + context, + hasIframe, + needSave, + retval; /** * Helper function to get an IE TextRange object for an element @@ -51,7 +57,7 @@ } } - var fn = { + fn = { /** * Get the contents of the textarea */ @@ -63,17 +69,20 @@ * in some browsers (IE/Opera) */ getSelection: function () { - var e = this.get( 0 ); - var retval = ''; - if ( $(e).is( ':hidden' ) ) { + var retval, range, + el = this.get( 0 ); + + if ( $(el).is( ':hidden' ) ) { // Do nothing + retval = ''; } else if ( document.selection && document.selection.createRange ) { - activateElementOnIE( e ); - var range = document.selection.createRange(); + activateElementOnIE( el ); + range = document.selection.createRange(); retval = range.text; - } else if ( e.selectionStart || e.selectionStart === 0 ) { - retval = e.value.substring( e.selectionStart, e.selectionEnd ); + } else if ( el.selectionStart || el.selectionStart === 0 ) { + retval = el.value.substring( el.selectionStart, el.selectionEnd ); } + return retval; }, /** @@ -88,6 +97,7 @@ encapsulateSelection: function ( options ) { return this.each( function () { var selText, scrollTop, insertText, + isSample, range, range2, range3, startPos, endPos, pre = options.pre, post = options.post; @@ -120,9 +130,10 @@ * Wrap each line of the selected text with pre and post */ function doSplitLines( selText, pre, post ) { - var insertText = ''; - var selTextArr = selText.split( '\n' ); - for ( var i = 0; i < selTextArr.length; i++ ) { + 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'; @@ -131,7 +142,7 @@ return insertText; } - var isSample = false; + isSample = false; if ( this.style.display === 'none' ) { // Do nothing } else if ( document.selection && document.selection.createRange ) { @@ -150,7 +161,7 @@ selText = $(this).textSelection( 'getSelection' ); scrollTop = this.scrollTop; - var range = document.selection.createRange(); + range = document.selection.createRange(); checkSelectedText(); insertText = pre + selText + post; @@ -158,20 +169,20 @@ insertText = doSplitLines( selText, pre, post ); } if ( options.ownline && range.moveStart ) { - var range2 = document.selection.createRange(); + range2 = document.selection.createRange(); range2.collapse(); range2.moveStart( 'character', -1 ); // FIXME: Which check is correct? - if ( range2.text !== "\r" && range2.text !== "\n" && range2.text !== "" ) { - insertText = "\n" + insertText; - pre += "\n"; + if ( range2.text !== '\r' && range2.text !== '\n' && range2.text !== '' ) { + insertText = '\n' + insertText; + pre += '\n'; } - var range3 = document.selection.createRange(); + range3 = document.selection.createRange(); range3.collapse( false ); range3.moveEnd( 'character', 1 ); - if ( range3.text !== "\r" && range3.text !== "\n" && range3.text !== "" ) { - insertText += "\n"; - post += "\n"; + if ( range3.text !== '\r' && range3.text !== '\n' && range3.text !== '' ) { + insertText += '\n'; + post += '\n'; } } @@ -192,8 +203,8 @@ } selText = $(this).textSelection( 'getSelection' ); - var startPos = this.selectionStart; - var endPos = this.selectionEnd; + startPos = this.selectionStart; + endPos = this.selectionEnd; scrollTop = this.scrollTop; checkSelectedText(); if ( options.selectionStart !== undefined @@ -210,13 +221,13 @@ insertText = doSplitLines( selText, pre, post ); } if ( options.ownline ) { - if ( startPos !== 0 && this.value.charAt( startPos - 1 ) !== "\n" && this.value.charAt( startPos - 1 ) !== "\r" ) { - insertText = "\n" + insertText; - pre += "\n"; + if ( startPos !== 0 && this.value.charAt( startPos - 1 ) !== '\n' && this.value.charAt( startPos - 1 ) !== '\r' ) { + insertText = '\n' + insertText; + pre += '\n'; } - if ( this.value.charAt( endPos ) !== "\n" && this.value.charAt( endPos ) !== "\r" ) { - insertText += "\n"; - post += "\n"; + if ( this.value.charAt( endPos ) !== '\n' && this.value.charAt( endPos ) !== '\r' ) { + insertText += '\n'; + post += '\n'; } } this.value = this.value.substring( 0, startPos ) + insertText + @@ -224,9 +235,9 @@ // Setting this.value scrolls the textarea to the top, restore the scroll position this.scrollTop = scrollTop; if ( window.opera ) { - pre = pre.replace( /\r?\n/g, "\r\n" ); - selText = selText.replace( /\r?\n/g, "\r\n" ); - post = post.replace( /\r?\n/g, "\r\n" ); + pre = pre.replace( /\r?\n/g, '\r\n' ); + selText = selText.replace( /\r?\n/g, '\r\n' ); + post = post.replace( /\r?\n/g, '\r\n' ); } if ( isSample && options.selectPeri && !options.splitlines ) { this.selectionStart = startPos + pre.length; @@ -255,7 +266,21 @@ */ getCaretPosition: function ( options ) { function getCaret( e ) { - var caretPos = 0, endPos = 0; + var caretPos = 0, + endPos = 0, + preText, rawPreText, periText, + rawPeriText, postText, rawPostText, + // IE Support + preFinished, + periFinished, + postFinished, + // Range containing text in the selection + periRange, + // Range containing text before the selection + preRange, + // Range containing text after the selection + postRange; + if ( document.selection && document.selection.createRange ) { // IE doesn't properly report non-selected caret position through // the selection ranges when textarea isn't focused. This can @@ -263,26 +288,24 @@ // whatever we do later (bug 31847). activateElementOnIE( e ); - // 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 = rangeForElementIE( e ); + preFinished = false; + periFinished = false; + postFinished = false; + periRange = document.selection.createRange().duplicate(); + + preRange = rangeForElementIE( e ), // Move the end where we need it preRange.setEndPoint( 'EndToStart', periRange ); - // Create range containing text after the selection - var postRange = rangeForElementIE( e ); + + postRange = rangeForElementIE( 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 @@ -295,7 +318,7 @@ } else { preRange.moveEnd( 'character', -1 ); if ( preRange.text === preText ) { - rawPreText += "\r\n"; + rawPreText += '\r\n'; } else { preFinished = true; } @@ -307,7 +330,7 @@ } else { periRange.moveEnd( 'character', -1 ); if ( periRange.text === periText ) { - rawPeriText += "\r\n"; + rawPeriText += '\r\n'; } else { periFinished = true; } @@ -319,15 +342,15 @@ } else { postRange.moveEnd( 'character', -1 ); if ( postRange.text === postText ) { - rawPostText += "\r\n"; + 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; + 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; @@ -342,6 +365,7 @@ */ setSelection: function ( options ) { return this.each( function () { + var selection, length, newLines; if ( $(this).is( ':hidden' ) ) { // Do nothing } else if ( this.selectionStart || this.selectionStart === 0 ) { @@ -356,10 +380,10 @@ this.selectionEnd = options.end; } } else if ( document.body.createTextRange ) { - var selection = rangeForElementIE( this ); - var length = this.value.length; + selection = rangeForElementIE( this ); + 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 ); + newLines = this.value.match( /\n/g ); if ( newLines ) { length = length - newLines.length; } @@ -370,7 +394,7 @@ // Silence that error try { selection.select(); - } catch( e ) { } + } catch ( e ) { } } }); }, @@ -390,20 +414,22 @@ return Math.floor( e.scrollWidth / ( $.client.profile().platform === 'linux' ? 7 : 8 ) ); } function getCaretScrollPosition( e ) { - var i, j; // 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; + var i, j, + nextSpace, + text = e.value.replace( /\r/g, '' ), + caret = $( e ).textSelection( 'getCaretPosition' ), + lineLength = getLineLength( e ), + row = 0, + charInLine = 0, + lastSpaceInLine = 0; + for ( i = 0; i < caret; i++ ) { charInLine++; if ( text.charAt( i ) === ' ' ) { lastSpaceInLine = charInLine; - } else if ( text.charAt( i ) === "\n" ) { + } else if ( text.charAt( i ) === '\n' ) { lastSpaceInLine = 0; charInLine = 0; row++; @@ -416,11 +442,11 @@ } } } - var nextSpace = 0; + nextSpace = 0; for ( j = caret; j < caret + lineLength; j++ ) { if ( text.charAt( j ) === ' ' || - text.charAt( j ) === "\n" || + text.charAt( j ) === '\n' || caret === text.length ) { nextSpace = j; @@ -434,11 +460,12 @@ return ( $.client.profile().platform === 'mac' ? 13 : ( $.client.profile().platform === 'linux' ? 15 : 16 ) ) * row; } return this.each(function () { + var scroll, range, savedRange, pos, oldScrollTop; if ( $(this).is( ':hidden' ) ) { // Do nothing } else if ( this.selectionStart || this.selectionStart === 0 ) { // Mozilla - var scroll = getCaretScrollPosition( this ); + scroll = getCaretScrollPosition( this ); if ( options.force || scroll < $(this).scrollTop() || scroll > $(this).scrollTop() + $(this).height() ) { $(this).scrollTop( scroll ); @@ -453,10 +480,10 @@ * 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 = document.body.createTextRange(); + savedRange = document.selection.createRange(); + pos = $(this).textSelection( 'getCaretPosition' ); + oldScrollTop = this.scrollTop; range.moveToElementText( this ); range.collapse(); range.move( 'character', pos + 1); @@ -526,16 +553,16 @@ break; } - var context = $(this).data( 'wikiEditor-context' ); - var hasIframe = typeof context !== 'undefined' && context && typeof context.$iframe !== 'undefined'; + context = $(this).data( 'wikiEditor-context' ); + hasIframe = context !== undefined && context && context.$iframe !== undefined; // IE selection restore voodoo - var needSave = false; + needSave = false; if ( hasIframe && context.savedSelection !== null ) { context.fn.restoreSelection(); needSave = true; } - var retval = ( hasIframe ? context.fn : fn )[command].call( this, options ); + retval = ( hasIframe ? context.fn : fn )[command].call( this, options ); if ( hasIframe && needSave ) { context.fn.saveSelection(); }