diff --git a/app/assets/javascripts/lib/jquery.highlighttextarea.js b/app/assets/javascripts/lib/jquery.highlighttextarea.js
deleted file mode 100755
index de6791176..000000000
--- a/app/assets/javascripts/lib/jquery.highlighttextarea.js
+++ /dev/null
@@ -1,699 +0,0 @@
-/*!
- * jQuery highlightTextarea
- * Copyright 2014-2015 Damien "Mistic" Sorel (http://www.strangeplanet.fr)
- * Licensed under MIT (http://opensource.org/licenses/MIT)
- */
-
-//= require jquery
-
-(function($){
- "use strict";
-
- var mouseOverElement = null;
- var isNumeric = function(n) {
- return !isNaN(parseFloat(n)) && isFinite(n);
- };
-
- // Highlighter CLASS DEFINITON
- // ===============================
- var Highlighter = function($el, options) {
- // global variables
- this.settings = $.extend({}, Highlighter.DEFAULTS);
- this.scrollbarWidth = Utilities.getScrollbarWidth();
- this.isInput = $el[0].tagName.toLowerCase()=='input';
- this.active = false;
- this.matches = [];
-
- // build HTML
- this.$el = $el;
-
- this.$el.wrap('
');
- this.$main = this.$el.parent();
-
- this.$main.prepend('');
- this.$container = this.$main.children().first();
- this.$highlighter = this.$container.children();
-
- this.setOptions(options);
-
- // set id
- if (this.settings.id) {
- this.$main[0].id = this.settings.id;
- }
-
- // resizable
- if (this.settings.resizable) {
- this.applyResizable();
- }
-
- // run
- this.updateCss();
- this.bindDocumentEvents();
- this.bindEvents();
- this.highlight();
- };
-
- Highlighter.DEFAULTS = {
- words: {},
- ranges: {},
- color: '#ffff00',
- caseSensitive: true,
- wordsOnly: false,
- resizable: false,
- resizableOptions: {},
- id: '',
- debug: false
- };
-
- // PUBLIC METHODS
- // ===============================
- /*
- * Refresh highlight
- */
- Highlighter.prototype.highlight = function() {
- var text = this.$el.val(),
- that = this;
- that.spacer = '';
- if (this.settings.wordsOnly ) {
- that.spacer = '\\b';
- }
-
- function htmlDecode(input) {
- return $('').text(input).html();
- }
-
- // Encode text before inserting into so that the textarea and
- // overlay don't get out if sync when the textarea contains something
- // HTML (e.g. "&" or
).
- text = htmlDecode(text);
-
- var matches = [];
- $.each(this.settings.words, function(color, words) {
- var wordsRe = htmlDecode(words.join("|"));
- var re = that.spacer + '(' + wordsRe + ')' + that.spacer;
- var regex = new RegExp(re, that.regParam);
-
- var wordMatches = text.match(regex);
- if (wordMatches) {
- var evaluated = [];
- $.each(words, function(index, match) {
- match = htmlDecode(match);
-
- matches.push(match);
- if (evaluated.indexOf(match) === -1) {
- text = text.replace(
- new RegExp(match, that.regParam),
- function(innerMatch, start, contents) {
- var encodedMatch = innerMatch
- .replace(/[&"<>]/g, function (c) {
- return {
- '&': "&",
- '"': """,
- '<': "<",
- '>': ">"
- }[c];
- });
-
- return '' + encodedMatch + '';
- }
- );
-
- evaluated.push(match);
- }
- });
- }
- });
-
- $.each(this.settings.ranges, function(i, range) {
- if (range.start < text.length) {
- text = Utilities.strInsert(text, range.end, '');
-
- var mark = '";
-
- text = Utilities.strInsert(text, range.start, mark);
- }
- });
-
- if (matches.length !== this.matches.length) {
- this.matches = matches;
- var matchesChangedEvent = $.Event('matchesChanged');
- matchesChangedEvent.matches = this.matches;
- this.$el.trigger(matchesChangedEvent);
- }
-
- this.$highlighter.html(text);
- this.updateSizePosition();
- };
-
- /*
- * Change highlighted words
- * @param words {mixed}
- */
- Highlighter.prototype.setWords = function(words) {
- this.setOptions({ words: words, ranges: {} });
- };
-
- /*
- * Change highlighted ranges
- * @param ranges {mixed}
- */
- Highlighter.prototype.setRanges = function(ranges) {
- this.setOptions({ words: {}, ranges: ranges });
- };
-
- /*
- * Enable highlight and events
- */
- Highlighter.prototype.enable = function() {
- this.bindEvents();
- this.highlight();
- };
-
- /*
- * Disable highlight and events
- */
- Highlighter.prototype.disable = function() {
- this.unbindEvents();
- this.$highlighter.empty();
- };
-
- /*
- * Remove the plugin
- */
- Highlighter.prototype.destroy = function() {
- this.disable();
-
- Utilities.cloneCss(this.$container, this.$el, [
- 'background-image','background-color','background-position','background-repeat',
- 'background-origin','background-clip','background-size','background-attachment'
- ]);
-
- this.$main.replaceWith(this.$el);
-
- this.$el.removeData('highlighter');
- };
-
- // PRIVATE METHODS
- // ===============================
- /*
- * Change options
- * @param options {object}
- */
- Highlighter.prototype.setOptions = function(options) {
- if (typeof options != 'object' || $.isEmptyObject(options)) {
- return;
- }
-
- $.extend(this.settings, options);
- this.regParam = this.settings.caseSensitive ? 'gm' : 'gim';
-
- if (!$.isEmptyObject(this.settings.words)) {
- this.settings.words = Utilities.cleanWords(this.settings.words, this.settings.color);
- this.settings.ranges = {};
- }
- else if (!$.isEmptyObject(this.settings.ranges)) {
- this.settings.words = {};
- this.settings.ranges = Utilities.cleanRanges(this.settings.ranges, this.settings.color);
- }
-
- if (this.settings.debug) {
- this.$main.addClass('debug');
- }
- else {
- this.$main.removeClass('debug');
- }
-
- if (this.active) {
- this.highlight();
- }
- };
-
- /*
- * Attach event listeners for document-level events. These should only be bound once, not every time the plugin is used.
- */
- Highlighter.prototype.bindDocumentEvents = function() {
- if(Highlighter.documentEventsBound) {
- return;
- }
-
- //Trigger simulated mouseout and mouseover events on highlightTextarea mark elements.
- $(document).bind('mousemove', function(e) {
- var mouseX = e.pageX;
- var mouseY = e.pageY;
- var lastMouseOverElement = mouseOverElement;
- mouseOverElement = null;
-
- //Mouse can only be "over" one element at a time; loop through all highlightTextarea mark elements until we find one that is moused over.
- $('.highlightTextarea mark').each(function(index) {
- var $this = $(this);
- var pos = $this.offset();
- var top = pos.top;
- var left = pos.left;
- var height = $this.height();
- var width = $this.width();
-
- if (mouseX >= left && mouseY >= top && mouseX <= left + width && mouseY <= top + height) {
- mouseOverElement = this;
- return;
- }
- });
-
- if(mouseOverElement != lastMouseOverElement) {
- if(lastMouseOverElement != null) {
- $(lastMouseOverElement).trigger('mouseout');
- }
- if(mouseOverElement != null) {
- $(mouseOverElement).trigger('mouseover');
- }
- }
- });
-
- Highlighter.documentEventsBound = true;
- };
-
- /*
- * Attach event listeners
- */
- Highlighter.prototype.bindEvents = function() {
- if (this.active) {
- return;
- }
- this.active = true;
-
- var that = this;
-
- // prevent positioning errors by always focusing the textarea
- this.$highlighter.bind({
- 'this.highlighter': function() {
- that.$el.focus();
- }
- });
-
- // add triggers to textarea
- this.$el.bind({
- 'input.highlightTextarea': Utilities.throttle(function() {
- this.highlight();
- }, 100, this),
-
- 'resize.highlightTextarea': Utilities.throttle(function() {
- this.updateSizePosition(true);
- }, 50, this),
-
- 'scroll.highlightTextarea select.highlightTextarea': Utilities.throttle(function() {
- this.updateSizePosition();
- }, 50, this)
- });
-
- if (this.isInput) {
- this.$el.bind({
- // Prevent Cmd-Left Arrow and Cmd-Right Arrow on Mac strange behavior
- 'keydown.highlightTextarea keypress.highlightTextarea keyup.highlightTextarea': function() {
- setTimeout($.proxy(that.updateSizePosition, that), 1);
- },
-
- // Force Chrome behavior on all browsers: reset input position on blur
- 'blur.highlightTextarea': function() {
- this.value = this.value;
- this.scrollLeft = 0;
- that.updateSizePosition.call(that);
- }
- });
- }
- };
-
- /*
- * Detach event listeners
- */
- Highlighter.prototype.unbindEvents = function() {
- if (!this.active) {
- return;
- }
- this.active = false;
-
- this.$highlighter.off('.highlightTextarea');
- this.$el.off('.highlightTextarea');
- };
-
- /*
- * Update CSS of wrapper and containers
- */
- Highlighter.prototype.updateCss = function() {
- // the main container has the same size and position than the original textarea
- Utilities.cloneCss(this.$el, this.$main, [
- 'float','vertical-align'
- ]);
- this.$main.css({
- 'width': this.$el.outerWidth(true),
- 'height': this.$el.outerHeight(true)
- });
-
- // the highlighter container is positionned at "real" top-left corner of the textarea and takes its background
- Utilities.cloneCss(this.$el, this.$container, [
- 'background-image','background-color','background-position','background-repeat',
- 'background-origin','background-clip','background-size','background-attachment',
- 'padding-top','padding-right','padding-bottom','padding-left'
- ]);
- this.$container.css({
- 'top': Utilities.toPx(this.$el.css('margin-top')) + Utilities.toPx(this.$el.css('border-top-width')),
- 'left': Utilities.toPx(this.$el.css('margin-left')) + Utilities.toPx(this.$el.css('border-left-width')),
- 'width': this.$el.width(),
- 'height': this.$el.height()
- });
-
- // the highlighter has the same size than the "inner" textarea and must have the same font properties
- Utilities.cloneCss(this.$el, this.$highlighter, [
- 'font-size','font-family','font-style','font-weight','font-variant','font-stretch',
- 'vertical-align','word-spacing','text-align','letter-spacing', 'text-rendering'
- ]);
-
- // now make the textarea transparent to see the highlighter through
- this.$el.css({
- 'background': 'none'
- });
- };
-
- /*
- * Apply jQueryUi Resizable if available
- */
- Highlighter.prototype.applyResizable = function() {
- if (jQuery.ui) {
- var resizableOptionsDefaults = {
- 'handles': 'se',
- 'resize': Utilities.throttle(function() {
- this.updateSizePosition(true);
- }, 50, this)
- };
- var resizableOptions = $.extend({}, resizableOptionsDefaults, this.settings.resizableOptions);
- this.$el.resizable(resizableOptions);
- }
- };
-
- /*
- * Update size and position of the highlighter
- * @param forced {boolean} true to resize containers
- */
- Highlighter.prototype.updateSizePosition = function(forced) {
- // resize containers
- if (forced) {
- this.$main.css({
- 'width': this.$el.outerWidth(true),
- 'height': this.$el.outerHeight(true)
- });
- this.$container.css({
- 'width': this.$el.width(),
- 'height': this.$el.height()
- });
- }
-
- var padding = 0, width;
-
- if (!this.isInput) {
- // account for vertical scrollbar width
- if (this.$el.css('overflow') == 'scroll' ||
- this.$el.css('overflow-y') == 'scroll' ||
- (
- this.$el.css('overflow') != 'hidden' &&
- this.$el.css('overflow-y') != 'hidden' &&
- this.$el[0].clientHeight < this.$el[0].scrollHeight
- )
- ) {
- padding = this.scrollbarWidth;
- }
-
- width = this.$el.width()-padding;
- }
- else {
- // TODO: There's got to be a better way of going about this than just using 99999px...
- width = 99999;
- }
-
- this.$highlighter.css({
- 'width': width,
- 'height': this.$el.height() + this.$el.scrollTop(),
- 'top': -this.$el.scrollTop(),
- 'left': -this.$el.scrollLeft()
- });
- };
-
-
- // Utilities CLASS DEFINITON
- // ===============================
- var Utilities = function(){};
-
- /*
- * Get the scrollbar with on this browser
- */
- Utilities.getScrollbarWidth = function() {
- var parent = $('').appendTo('body'),
- child = parent.children(),
- width = child.innerWidth() - child.height(100).innerWidth();
-
- parent.remove();
-
- return width;
- };
-
- /*
- * Copy a list of CSS properties from one object to another
- * @param from {jQuery}
- * @param to {jQuery}
- * @param what {string[]}
- */
- Utilities.cloneCss = function(from, to, what) {
- for (var i=0, l=what.length; i ').appendTo('body');
- value = Math.round(parseFloat(value.replace('em', '')) * el.height());
- el.remove();
- return value;
- }
- else if (value != value.replace('px', '')) {
- return parseInt(value.replace('px', ''));
- }
- else {
- return parseInt(value);
- }
- };
-
- /*
- * Converts HTMl entities
- * @param str {string}
- * @return {string}
- */
- Utilities.htmlEntities = function(str) {
- if (str) {
- return $('').text(str).html();
- }
- else {
- return '';
- }
- };
-
- /*
- * Inserts a string in another string at given position
- * @param string {string}
- * @param index {int}
- * @param value {string}
- * @return {string}
- */
- Utilities.strInsert = function(string, index, value) {
- return string.slice(0, index) + value + string.slice(index);
- };
-
- /*
- * Apply throttling to a callback
- * @param callback {function}
- * @param delay {int} milliseconds
- * @param context {object|null}
- * @return {function}
- */
- Utilities.throttle = function(callback, delay, context) {
- var state = {
- pid: null,
- last: 0
- };
-
- return function() {
- var elapsed = new Date().getTime() - state.last,
- args = arguments,
- that = this;
-
- function exec() {
- state.last = new Date().getTime();
-
- if (context) {
- return callback.apply(context, Array.prototype.slice.call(args));
- }
- else {
- return callback.apply(that, Array.prototype.slice.call(args));
- }
- }
-
- if (elapsed > delay) {
- return exec();
- }
- else {
- clearTimeout(state.pid);
- state.pid = setTimeout(exec, delay - elapsed);
- }
- };
- };
-
- /*
- * Formats a list of words into a hash of arrays (Color => Words list)
- * @param words {mixed}
- * @param color {string} default color
- * @return {object[]}
- */
- Utilities.cleanWords = function(words, color) {
- var out = {};
-
- if (!$.isArray(words)) {
- words = [words];
- }
-
- for (var i=0, l=words.length; i Ranges list)
- * @param ranges {mixed}
- * @param color {string} default color
- * @return {object[]}
- */
- Utilities.cleanRanges = function(ranges, color) {
- var out = [];
-
- if ($.isPlainObject(ranges) || isNumeric(ranges[0])) {
- ranges = [ranges];
- }
-
- for (var i=0, l=ranges.length; i= range.end) {
- $.error('Invalid range end/start');
- }
- if (range.start < current) {
- $.error('Ranges overlap');
- }
- current = range.end;
- });
-
- out.reverse();
-
- return out;
- };
-
-
- // JQUERY PLUGIN DEFINITION
- // ===============================
- $.fn.highlightTextarea = function(option) {
- var args = arguments;
-
- return this.each(function() {
- var $this = $(this),
- data = $this.data('highlighter'),
- options = typeof option == 'object' && option;
-
- if (!data && option == 'destroy') {
- return;
- }
- if (!data) {
- data = new Highlighter($this, options);
- $this.data('highlighter', data);
- }
- if (typeof option == 'string') {
- data[option].apply(data, Array.prototype.slice.call(args, 1));
- }
- });
- };
-}(window.jQuery || window.Zepto));
diff --git a/app/assets/stylesheets/jquery.highlighttextarea.scss b/app/assets/stylesheets/jquery.highlighttextarea.scss
deleted file mode 100755
index eb9f2f6b6..000000000
--- a/app/assets/stylesheets/jquery.highlighttextarea.scss
+++ /dev/null
@@ -1,52 +0,0 @@
-/*!
- * jQuery highlightTextarea
- * Copyright 2014-2015 Damien "Mistic" Sorel (http://www.strangeplanet.fr)
- * Licensed under MIT (http://opensource.org/licenses/MIT)
- */
-
-.highlightTextarea {
- position:relative;
-}
-.highlightTextarea .highlightTextarea-container {
- position:absolute;
- margin:0;
- overflow:hidden;
-}
-.highlightTextarea .highlightTextarea-highlighter {
- position:relative;
- border:none;
- padding:0;
- margin:0;
- color:transparent;
- cursor:text;
- overflow:hidden;
- white-space:pre-wrap;
- word-wrap:break-word;
-}
- .highlightTextarea.debug .highlightTextarea-highlighter {
- color:#f00;
- border:1px solid #f00;
- margin:-1px;
- }
-.highlightTextarea mark {
- line-height:inherit;
- color:transparent;
- margin:0;
- padding:0;
-}
-.highlightTextarea textarea,
-.highlightTextarea input {
- position:absolute;
- left:0;
- top:0;
- resize:none;
- white-space:pre-wrap;
- word-wrap:break-word;
-}
-.highlightTextarea .ui-wrapper {
- margin:0 !important;
-}
-.highlightTextarea .ui-resizable-se {
- bottom:15px;
- right:0px;
-}