mostly cross-browser compatibility enhancements
This commit is contained in:
@@ -34,6 +34,7 @@ Changelog
|
||||
- Script execution is now done via an async js request, preventing die() and exception to mess up the entire console
|
||||
- Added a status bar with char/line display
|
||||
- Added a toggle button to expand/collapse all krumo sub-trees at once
|
||||
- Cross-browser compatibility enhancements
|
||||
- 1.0.0
|
||||
- Initial Public Release
|
||||
|
||||
|
||||
+103
-13
@@ -16,7 +16,6 @@
|
||||
* Source on Github http://github.com/Seldaek/jquery-selections
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* sets the caret position
|
||||
*
|
||||
@@ -24,8 +23,19 @@
|
||||
* @see $.fn.setSelection
|
||||
*/
|
||||
$.fn.setCaret = function(index) {
|
||||
this.setSelection(index);
|
||||
var range, elem;
|
||||
elem = this.get(0);
|
||||
|
||||
if ($.browser.opera) {
|
||||
match = this.val().match(/\n/g);
|
||||
if (match) {
|
||||
newlines = match.length;
|
||||
index += newlines;
|
||||
}
|
||||
}
|
||||
|
||||
this.setSelection(index);
|
||||
};
|
||||
|
||||
/**
|
||||
* returns the caret position, or 0 if the element has no caret
|
||||
@@ -33,28 +43,58 @@
|
||||
* @return int
|
||||
*/
|
||||
$.fn.getCaret = function() {
|
||||
var elem, range, elemRange, elemRangeCopy;
|
||||
var elem, range, elemRange, elemRangeCopy, value, caret, pos;
|
||||
elem = this.get(0);
|
||||
|
||||
value = $(elem).val();
|
||||
|
||||
// standard browsers
|
||||
if (elem.selectionStart) {
|
||||
return elem.selectionStart;
|
||||
caret = elem.selectionStart;
|
||||
} else if (document.selection) {
|
||||
// old IE handling
|
||||
elem.focus();
|
||||
|
||||
range = document.selection.createRange();
|
||||
if (range === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
elemRange = elem.createTextRange(),
|
||||
// handle input texts
|
||||
if (elem.nodeName === 'INPUT') {
|
||||
elemRange = elem.createTextRange();
|
||||
elemRangeCopy = elemRange.duplicate();
|
||||
elemRange.moveToBookmark(range.getBookmark());
|
||||
elemRangeCopy.setEndPoint('EndToStart', elemRange);
|
||||
caret = elemRangeCopy.text.length;
|
||||
} else {
|
||||
// handle textareas
|
||||
elemRangeCopy = range.duplicate();
|
||||
elemRangeCopy.moveToElementText(elem);
|
||||
|
||||
return elemRangeCopy.text.length;
|
||||
pos = 0;
|
||||
if (range.text.length > 1) {
|
||||
pos = Math.max(0, pos - range.text.length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
caret = -1 + pos;
|
||||
elemRangeCopy .moveStart('character', pos);
|
||||
|
||||
while (elemRangeCopy.inRange(range)) {
|
||||
elemRangeCopy.moveStart('character');
|
||||
caret++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
caret = 0;
|
||||
}
|
||||
|
||||
if ($.browser.opera) {
|
||||
value = value.replace(/\r?\n/g, "\r\n").substr(0, caret);
|
||||
match = value.match(/\r\n/g);
|
||||
if (match) {
|
||||
newlines = match.length;
|
||||
caret -= newlines;
|
||||
}
|
||||
}
|
||||
|
||||
return caret;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -69,10 +109,12 @@
|
||||
elem = this.get(0);
|
||||
end = end || start;
|
||||
|
||||
// standard browsers
|
||||
if (elem.setSelectionRange) {
|
||||
elem.focus();
|
||||
elem.setSelectionRange(start, end);
|
||||
} else if (elem.createTextRange) {
|
||||
// old IE handling
|
||||
range = elem.createTextRange();
|
||||
range.collapse(true);
|
||||
range.moveEnd('character', end);
|
||||
@@ -83,6 +125,55 @@
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* reads the text the user selected
|
||||
*
|
||||
* @param int start index of the beginning of the selection
|
||||
* @param int end index of the end of the selection
|
||||
* @return string
|
||||
*/
|
||||
$.fn.getSelectedText = function() {
|
||||
var elem = this.get(0);
|
||||
|
||||
// standard browsers
|
||||
if (elem.selectionStart) {
|
||||
return elem.value.substr(elem.selectionStart, elem.selectionEnd);
|
||||
}
|
||||
|
||||
// old IE
|
||||
if (document.selection) {
|
||||
elem.focus();
|
||||
return document.selection.createRange().text;
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* injects the given text in place of the current selection
|
||||
*
|
||||
* @param string text
|
||||
* @return object chainable
|
||||
*/
|
||||
$.fn.replaceSelection = function(text) {
|
||||
var elem = this.get(0);
|
||||
|
||||
// standard browsers
|
||||
if (elem.selectionStart) {
|
||||
elem.value = elem.value.substr(0, elem.selectionStart) + text + elem.value.substr(elem.selectionEnd, elem.value.length);
|
||||
return this;
|
||||
}
|
||||
|
||||
// old IE
|
||||
if (document.selection) {
|
||||
elem.focus();
|
||||
document.selection.createRange().text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* injects the given text at the current caret position
|
||||
*
|
||||
@@ -99,6 +190,5 @@
|
||||
$elem.setCaret(caret + text.length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
};
|
||||
}(jQuery));
|
||||
+26
-14
@@ -13,20 +13,28 @@
|
||||
*/
|
||||
$(function() {
|
||||
|
||||
var updateStatusBar;
|
||||
var updateStatusBar, handleKeyPress;
|
||||
|
||||
// updates the text of the status bar
|
||||
updateStatusBar = function() {
|
||||
var caret, part, matches;
|
||||
var caret, part, matches, charCount, lineCount;
|
||||
caret = $('textarea[name="code"]').getCaret();
|
||||
part = $('textarea[name="code"]').val().substring(0, caret);
|
||||
matches = part.match(/(\r?\n)?([^\r\n]*)/g);
|
||||
part = $('textarea[name="code"]').val().substr(0, caret);
|
||||
matches = part.match(/(\n|[^\r\n]*$)/g);
|
||||
part = matches.length > 1 ? matches[matches.length - 2] : matches[0];
|
||||
$('.statusbar').text('Line: ' + Math.max(1, matches.length-1) + ', Column: ' + (matches.length > 2 ? part.length : part.length + 1));
|
||||
lineCount = Math.max(1, matches.length);
|
||||
// matched the first char of a line, so matches are only \n's
|
||||
if (part === "" || part === "\r\n" || part === "\n") {
|
||||
charCount = 1;
|
||||
} else {
|
||||
// matched another char, so we've got the current line as the next-to-last match
|
||||
charCount = part.length + 1;
|
||||
lineCount--;
|
||||
}
|
||||
$('.statusbar').text('Line: ' + lineCount + ', Column: ' + charCount);
|
||||
};
|
||||
|
||||
$('textarea[name="code"]')
|
||||
.keydown(function(e) {
|
||||
handleKeyPress = function(e) {
|
||||
var caret, part, matches;
|
||||
switch(e.keyCode) {
|
||||
case 9:
|
||||
@@ -43,13 +51,9 @@ $(function() {
|
||||
}
|
||||
|
||||
// indent automatically the new lines
|
||||
// skip because buggy in opera until they fix the preventDefault bug
|
||||
if ($.browser.opera) {
|
||||
return;
|
||||
}
|
||||
caret = $(this).getCaret();
|
||||
part = $(this).val().substring(0, caret);
|
||||
matches = part.match(/(\r?\n +)[^\r\n]*$/);
|
||||
part = $(this).val().substr(0, caret);
|
||||
matches = part.match(/(\n +)[^\r\n]*$/);
|
||||
if (matches) {
|
||||
$(this).val(function(idx, val) {
|
||||
return val.substring(0, caret) + matches[1] + val.substring(caret);
|
||||
@@ -61,11 +65,19 @@ $(function() {
|
||||
}
|
||||
|
||||
updateStatusBar();
|
||||
})
|
||||
};
|
||||
|
||||
$('textarea[name="code"]')
|
||||
.keyup(updateStatusBar)
|
||||
.click(updateStatusBar)
|
||||
.focus();
|
||||
|
||||
if ($.browser.opera) {
|
||||
$('textarea[name="code"]').keypress(handleKeyPress);
|
||||
} else {
|
||||
$('textarea[name="code"]').keydown(handleKeyPress);
|
||||
}
|
||||
|
||||
updateStatusBar();
|
||||
|
||||
$('input[name="subm"]').keyup(function(e) {
|
||||
|
||||
Reference in New Issue
Block a user