valSel.js is a cross-browser textarea and text input value and selection manipulation library plug-in for jQuery. It lets you determine the position of the cursor/selection in a textarea or text input field and change the text around it. Note that you should probably use MediaWiki's textSelection plugin instead (see below).
Please write on the talk page if you find this script useful and if you have any questions or suggestions. Thanks. If you are going to be using this script, you may want to add this page to your watchlist, so you get notified of any changes. Also, check out my other useful scripts.
You can see the source code here: User:V111P/js/valSel.js.
You can use MediaWiki's textSelection jQuery plugin [1] instead of this script, it seems to be loaded by default, so it makes no sense to load another script for the same functionality. It's API is not as nice, but you can write some wrapper functions around it. Here is an example:
mw.loader.using('jquery.textSelection');
// get and set the text and selection in a textarea
function valParts($el, textBefore, selText, textAfter) {
if (typeof textBefore == 'string') {
$el.val(textBefore + selText + textAfter);
var beforeLen = textBefore.length;
$el.textSelection('setSelection', {
'start': beforeLen,
'end': beforeLen + selText.length
});
return;
}
else {
var s = $el.textSelection('getCaretPosition', {startAndEnd: true} );
var text = $el.val().replace(/\r/g, '');
return [text.slice(0, s[0]), text.slice(s[0], s[1]), text.slice(s[1])];
}
}; // valParts
Important! Note that as of now (May 2014), jquery.textSelection does not remove carriage returns (\r's) from the text in IE 8 and below. That's probably because now there is a special version of jQuery for these browsers, but MediaWiki doesn't use it. However, the cursor position used is as if the \r's are not there. That's why always remember to remove all \r's when getting either the selected text or the whole text. IE 9 was only released in 2011, so the previous version should still be supported.
Here is an example code showing how you can load this script from another script.
First include the URL:
var valSelUrl = '//en.wikipedia.org/w/index.php?title=' // Backlink: [[User:V111P/js/valSel.js]]
+ 'User:V111P/js/valSel.js&action=raw&ctype=text/javascript';
If you don't need to do something with the script immediately, you can do a simple ajax call to load it (check for either of the jQuery methods first to verify it is not yet loaded):
if (!$.fn.valParts)
$.ajax({
url: valSelUrl,
dataType: 'script',
cache: true
});
If you need to do something with it as soon as it loads and executes, you need to do more than that. For example, if you need to run the function doSomething
:
function checkIfExecuted(objectToCheck, propToCheck, callback, cntr) {
if (typeof cntr == 'undefined') cntr = 50; // try for 5 seconds
if (objectToCheck[propToCheck])
callback();
else if (cntr > 0)
setTimeout(function () {
checkIfExecuted(objectToCheck, propToCheck, callback, cntr - 1);
}, 100);
}
if ($.fn.valParts)
doSomething();
else
$.ajax({
url: valSelUrl,
dataType: 'script',
cache: true,
success: function () {
checkIfExecuted($.fn, 'valParts', doSomething);
}
});
The function checkIfExecuted is needed because (sometimes, in some browsers) the success callback is called after the script file has been downloaded, but before it has been executed.[1] Also, do not use jQuery's getScript() method, because it disables the caching of the script file[2]. Instead, use ajax() as in the example above. You can also use mw.loader.load(url)
.
If you need to load several scripts instead of just one, the easiest way is to load them one after the other.
valSel.js is a jQuery plugin. To use it you call one of the methods listed below on a jQuery object containing (as a first element) the textarea or text input you want to work with. Note the relationship between selection and cursor position. If no text is currently selected, then the selection is said to be collapsed, having the same starting and ending position (the position of the cursor) and a length of zero.
Attention! Since not everything has been tested yet, if you notice something not working as advertized here, you should report it on the talk page, so I can fix it.
The text value of the textarea or text input element is normalized as through the jQuery's val()
method - all \r
characters are removed, so the lines are left separated only with \n
characters. (For example old versions of Internet Explorer separate the lines in the textareas with \r\n
. See also the article Newline for more information).
The parameter collapse
should be a number: 0
means keep the selection (this is the default), 1
(or any positive number) means collapse the selection to its end, -1
(or any negative number) means collapse the selection to its start.
In the listed method signatures below, the type of the parameters is given and the optional parameters are in square brackets. This of course is not legal JavaScript. Hopefully the examples will help clarify how to actually use the methods if you are confused.
valParts()
- returns an array with three strings - the first one is the text before the selection/cursor, the second one is the selected text (if any), and the third one is the text after the selection/cursor.valParts(textBefore, selText, textAfter)
- sets the text in the textarea/text input and sets the selection at the same time by specifying which text appears before, within, and after the selection.valParts(beforeSelAfterArray)
- as above, but the three strings are passed in an array as a single argument. Example: valParts(['This text is before the selection. ', 'This text is selected.', ' This text is after the selection.'])
valParts(fn)
- where fn
is a function that will be called.
undefined
(or false
), or an array with three string elements to replace the value in the textarea/text input as follows:
sel()
- returns an object with the following properties:
text
- the selected text. An example of getting the selected text: alert($('#wpTextarea1').sel().text);
start
, end
- the starting and ending position of the selection within the value of the textarea/text input. The ending position is greater than or equal to the starting position. Note that these are the positions within the normalized value (see the explanation above).length
- the length of the string text
sel(string newVal[, int collapse])
- the newVal
is the string to replace the current selection, or, if no text is currently selected, the string to be added at the cursor's position. The newly added text will be selected, unless a non-zero number is passed as a second argument (see the explanation for collapse
in the section #The collapse parameter above). Examples: $('#wpTextbox1').sel('((stub))', 1); $('#wpTextbox1').sel('((stub))');
sel(int newStartPos[, int newEndPos])
- sets the selection ends to the provided positions. (Note that no text is moved or changed here.) If the second parameter is not a number, then both the start and end positions of the selection will be set to the value passed as argument #1. Negative values are interpreted as zero, while values greater than the length of the textarea/text input value are interpreted as the same as the value's length. If you try to move the end of the selection before its start or its start after its end, the values will be swapped so that the start is again the smaller value (this may not be what you want!).sel(fn)
- where fn
is a function that will be called.
false
), or it should return a string to replace the current selection with, or an object with any (or none) of the following properties:
text
- a string to replace the current selection with;collapse
- a number, as explained above in #The collapse parameter (ignored if start
is given);start
and end
- the new start and end positions of the selection (end
defaults to the same value that start
is given). Negative values are interpreted as zero, while values greater than the length of the textarea/text input value are interpreted as the same as the value's length. If you try to move the end before the start or the start after the end, the values will be swapped so that start is again the smaller value (this may not be what you want!).Example of calling sel() with a function argument:
// If there is a selection, reduce its size by 5 by moving its end 5 character backward.
// If there are fewer that 5 characters in the selection, collapse the selection to its start.
$('#wpTextbox1').sel(function (currSelText, start, end, length) {
var reduceWith = (length > 5 ? 5 : length);
return {end: end - reduceWith}; // if it's negative that's the same as zero
}
// if the selection is "stub", replace it with {<nowiki/>{stub)),
// if it is "afd", replace it with {<nowiki/>{subst:afd)).
// Collapse the selection to its end
$('#wpTextbox1').sel(function (currSelText, start, end, length) {
var newSel;
switch (currSelText) {
case 'stub':
newSel = '{<nowiki/>{stub))';
break;
case 'afd':
newSel = '{<nowiki/>{subst:afd))';
break;
}
return {text: newSel, collapse: 1}; // if newSel is undefined here, nothing will happen
}
toStart
is true, collapses the selection to its start, otherwise collapses the selection to its end.This method can be used to insert text around the selection. The parameter collapse
is explained above in #The collapse parameter. The parameter include
dictates whether to include the inserted text in the selection or to insert it before/after it.
aroundSel(string surround, [bool include, [int collapse]])
- surround
is a string that will be inserted on both sides of the selection/cursor. See above for the explanation of the include
and collapse
parameters.aroundSel(string before, string after, [bool include, [int collapse]])
- like aroundSel(string surround, [bool include, [int collapse]])
, but here you can insert two different strings before and after the selection/cursor.aroundSel(string before, string prepend, string append, string after, [int collapse])
- before
and after
are inserted around the selection and are left outside of it, while prepend
and append
are inserted at the start and end of the selection itself. See above for the explanation of the collapse
parameter.Much of the code in this script is from Rangy Text Inputs (A version from 5 November 2010), a cross-browser textarea and text input library plug-in for jQuery, Copyright 2010, Tim Down, licensed under the MIT license. (The 2013 version is not much different).
You can use the code that I added in the file (the code not from Rangy Text Inputs) under CC0.