bunkerweb/ui/static/js/jquery.numberedtextarea.js
2022-06-03 17:24:14 +02:00

146 lines
4.8 KiB
JavaScript

/*
* NumberedTextarea - jQuery Plugin
* Textarea with line numbering
*
* Copyright (c) 2015 Dariusz Arciszewski
*
* Requires: jQuery v2.0+
*
* Licensed under the GPL licenses:
* http://www.gnu.org/licenses/gpl.html
*/
(function ($) {
$.fn.numberedtextarea = function(options) {
var settings = $.extend({
color: null, // Font color
borderColor: null, // Border color
class: null, // Add class to the 'numberedtextarea-wrapper'
allowTabChar: false, // If true Tab key creates indentation
}, options);
this.each(function() {
if(this.nodeName.toLowerCase() !== "textarea") {
console.log('This is not a <textarea>, so no way Jose...');
return false;
}
addWrapper(this, settings);
addLineNumbers(this, settings);
if(settings.allowTabChar) {
$(this).allowTabChar();
}
});
return this;
};
$.fn.allowTabChar = function() {
if (this.jquery) {
this.each(function() {
if (this.nodeType == 1) {
var nodeName = this.nodeName.toLowerCase();
if (nodeName == "textarea" || (nodeName == "input" && this.type == "text")) {
allowTabChar(this);
}
}
})
}
return this;
}
function addWrapper(element, settings) {
var wrapper = $('<div class="numberedtextarea-wrapper"></div>').insertAfter(element);
$(element).detach().appendTo(wrapper);
}
function addLineNumbers(element, settings) {
element = $(element);
var wrapper = element.parents('.numberedtextarea-wrapper');
// Get textarea styles to implement it on line numbers div
var paddingLeft = parseFloat(element.css('padding-left'));
var paddingTop = parseFloat(element.css('padding-top'));
var paddingBottom = parseFloat(element.css('padding-bottom'));
var lineNumbers = $('<div class="numberedtextarea-line-numbers"></div>').insertAfter(element);
element.css({
paddingLeft: paddingLeft + lineNumbers.width() + 'px'
}).on('input propertychange change keyup paste', function() {
renderLineNumbers(element, settings);
}).on('scroll', function() {
scrollLineNumbers(element, settings);
});
lineNumbers.css({
paddingLeft: paddingLeft + 'px',
paddingTop: paddingTop + 'px',
lineHeight: element.css('line-height'),
fontFamily: element.css('font-family'),
width: lineNumbers.width() - paddingLeft + 'px',
});
element.trigger('change');
}
function renderLineNumbers(element, settings) {
element = $(element);
var linesDiv = element.parent().find('.numberedtextarea-line-numbers');
var count = element.val().split("\n").length;
var paddingBottom = parseFloat(element.css('padding-bottom'));
linesDiv.find('.numberedtextarea-number').remove();
for(i = 1; i<=count; i++) {
var line = $('<div class="numberedtextarea-number numberedtextarea-number-' + i + '">' + i + '</div>').appendTo(linesDiv);
if(i === count) {
line.css('margin-bottom', paddingBottom + 'px');
}
}
}
function scrollLineNumbers(element, settings) {
element = $(element);
var linesDiv = element.parent().find('.numberedtextarea-line-numbers');
linesDiv.scrollTop(element.scrollTop());
}
function pasteIntoInput(el, text) {
el.focus();
if (typeof el.selectionStart == "number") {
var val = el.value;
var selStart = el.selectionStart;
el.value = val.slice(0, selStart) + text + val.slice(el.selectionEnd);
el.selectionEnd = el.selectionStart = selStart + text.length;
} else if (typeof document.selection != "undefined") {
var textRange = document.selection.createRange();
textRange.text = text;
textRange.collapse(false);
textRange.select();
}
}
function allowTabChar(el) {
$(el).keydown(function(e) {
if (e.which == 9) {
pasteIntoInput(this, "\t");
return false;
}
});
// For Opera, which only allows suppression of keypress events, not keydown
$(el).keypress(function(e) {
if (e.which == 9) {
return false;
}
});
}
}(jQuery));