Created
January 31, 2011 20:25
-
-
Save actsasbuffoon/804739 to your computer and use it in GitHub Desktop.
A very simple jQuery based textarea editor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is shamelessly copied from http://stackoverflow.com/questions/263743/how-to-get-cursor-position-in-textarea#answer-3373056 | |
function getInputSelection(el) { | |
var start = 0, end = 0, normalizedValue, range, textInputRange, len, endRange; | |
if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") { | |
start = el.selectionStart; | |
end = el.selectionEnd; | |
} | |
else { | |
range = document.selection.createRange(); | |
if (range && range.parentElement() == el) { | |
len = el.value.length; | |
normalizedValue = el.value.replace(/\r\n/g, "\n"); | |
textInputRange = el.createTextRange(); | |
textInputRange.moveToBookmark(range.getBookmark()); | |
endRange = el.createTextRange(); | |
endRange.collapse(false); | |
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) { | |
start = end = len; | |
} else { | |
start = -textInputRange.moveStart("character", -len); | |
start += normalizedValue.slice(0, start).split("\n").length - 1; | |
if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) { | |
end = len; | |
} else { | |
end = -textInputRange.moveEnd("character", -len); | |
end += normalizedValue.slice(0, end).split("\n").length - 1; | |
} | |
} | |
} | |
} | |
return { | |
start: start, | |
end: end | |
}; | |
} | |
// This is shamelessly copied from http://blog.vishalon.net/index.php/javascript-getting-and-setting-caret-position-in-textarea/ | |
function setCaretPosition(ctrl, pos){ | |
if(ctrl.setSelectionRange) | |
{ | |
ctrl.focus(); | |
ctrl.setSelectionRange(pos,pos); | |
} | |
else if (ctrl.createTextRange) { | |
var range = ctrl.createTextRange(); | |
range.collapse(true); | |
range.moveEnd('character', pos); | |
range.moveStart('character', pos); | |
range.select(); | |
} | |
} | |
// This is my contribution. | |
$("textarea.editor").live("keydown", function(e) { | |
// Turn tab presses into soft-spaces | |
if (e.keyCode == 9) { | |
e.preventDefault() | |
p = getInputSelection(e.target).start | |
cv = $(e.target).val() | |
$(e.target).val(cv.substr(0, p) + " " + cv.substr(p)) | |
setCaretPosition(e.target, p + 2) | |
} | |
// Make enter preserve indentation of the current line | |
else if (e.keyCode == 13) { | |
e.preventDefault() | |
p = getInputSelection(e.target).start | |
cv = $(e.target).val() | |
t = "" | |
for (i = p; i >= 0; i--) { | |
if (cv.substr(i, 1) == "\n") { | |
if (p != i || p == 0) { | |
t = cv.substr(i, p - i).replace(/\n/g, "").match(/^\s*/)[0] | |
break | |
} | |
} | |
} | |
$(e.target).text(cv.substr(0, p) + "\n" + t + cv.substr(p)) | |
setCaretPosition(e.target, p + t.length + 1) | |
} | |
// Tell backspace to delete two spaces if the only thing before the cursor is blank space divisible by 2 | |
else if (e.keyCode == 8) { | |
p = getInputSelection(e.target).start | |
cv = $(e.target).val() | |
t = "" | |
for (i = p; i >= 0; i--) { | |
if (cv.substr(i, 1) == "\n") { | |
if (p != i || p == 0) { | |
tmp = cv.substr(i, p - i).replace(/\n/g, "").match(/^\s*$/) | |
if (tmp) { | |
t = tmp[0] | |
} | |
break | |
} | |
} | |
} | |
if (t.length % 2 == 0 && t.length > 0) { | |
e.preventDefault() | |
$(e.target).val(cv.substr(0, p - 2) + cv.substr(p)) | |
setCaretPosition(e.target, p - 2) | |
} | |
} | |
// Make Home or Meta+Left hop to the first non-whitespace character on the line | |
else if (e.keyCode == 36 || (e.keyCode == 37 && e.metaKey)) { | |
p = getInputSelection(e.target).start | |
cv = $(e.target).val() | |
cl = "" | |
cs = 0 | |
for (i = p - 1; i >= 0; i--) { | |
if (cv.substr(i, 1) == "\n") { | |
cl = cv.substr(i, p - i) | |
cs = cl.match(/^\s*/)[0].length | |
break | |
} | |
} | |
e.preventDefault() | |
setCaretPosition(e.target, p - cl.length + cs) | |
} | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment