gritter: Accept jQuery or DOM objects for title and text

Teach Gritter to accept anything that jQuery's `.append()` method
accepts for the title and text of a popup message. This makes it
easier to safely build HTML messages with proper escaping of special
characters (to prevent XSS vulnerabilities).
This commit is contained in:
Richard Hansen 2020-10-19 20:19:08 -04:00 committed by John McLear
parent d680405f58
commit d35dbaaacc

View file

@ -9,6 +9,9 @@
* Version: 1.7.4 * Version: 1.7.4
* *
* Edited by Sebastian Castro <sebastian.castro@protonmail.com> on 2020-03-31 * Edited by Sebastian Castro <sebastian.castro@protonmail.com> on 2020-03-31
*
* Edited by Richard Hansen <rhansen@rhansen.org> on 2020-10-19 to accept jQuery or DOM objects for
* notification title and text.
*/ */
(function($){ (function($){
@ -77,17 +80,12 @@
_tpl_wrap_top: '<div id="gritter-container" class="top"></div>', _tpl_wrap_top: '<div id="gritter-container" class="top"></div>',
_tpl_wrap_bottom: '<div id="gritter-container" class="bottom"></div>', _tpl_wrap_bottom: '<div id="gritter-container" class="bottom"></div>',
_tpl_close: '', _tpl_close: '',
_tpl_title: '<h3 class="gritter-title">[[title]]</h3>', _tpl_title: $('<h3>').addClass('gritter-title'),
_tpl_item: [ _tpl_item: ($('<div>').addClass('popup gritter-item')
'<div id="gritter-item-[[number]]" class="popup gritter-item [[item_class]]">', .append($('<div>').addClass('popup-content')
'<div class="popup-content">', .append($('<div>').addClass('gritter-content'))
'<div class="gritter-content">', .append($('<div>').addClass('gritter-close')
'[[title]]', .append($('<i>').addClass('buttonicon buttonicon-times'))))),
'<p>[[text]]</p>',
'</div>',
'<div class="gritter-close"><i class="buttonicon buttonicon-times"></i></div>',
'</div>',
'</div>'].join(''),
/** /**
@ -127,8 +125,7 @@
} }
this._item_count++; this._item_count++;
var number = this._item_count, var number = this._item_count;
tmp = this._tpl_item;
// Assign callbacks // Assign callbacks
$(['before_open', 'after_open', 'before_close', 'after_close']).each(function(i, val){ $(['before_open', 'after_open', 'before_close', 'after_close']).each(function(i, val){
@ -145,15 +142,17 @@
// String replacements on the template // String replacements on the template
if(title){ if(title){
title = this._str_replace('[[title]]',title,this._tpl_title); title = this._tpl_title.clone().append(title);
}else{ }else{
title = ''; title = '';
} }
tmp = this._str_replace( const tmp = this._tpl_item.clone();
['[[title]]', '[[text]]', '[[number]]', '[[item_class]]'], tmp.attr('id', `gritter-item-${number}`);
[title, text, this._item_count, item_class], tmp tmp.addClass(item_class);
); tmp.find('.gritter-content')
.append(title)
.append(typeof text === 'string' ? $('<p>').html(text) : text);
// If it's false, don't show another gritter message // If it's false, don't show another gritter message
if(this['_before_open_' + number]() === false){ if(this['_before_open_' + number]() === false){
@ -327,49 +326,6 @@
}, },
/**
* An extremely handy PHP function ported to JS, works well for templating
* @private
* @param {String/Array} search A list of things to search for
* @param {String/Array} replace A list of things to replace the searches with
* @return {String} sa The output
*/
_str_replace: function(search, replace, subject, count){
var i = 0, j = 0, temp = '', repl = '', sl = 0, fl = 0,
f = [].concat(search),
r = [].concat(replace),
s = subject,
ra = r instanceof Array, sa = s instanceof Array;
s = [].concat(s);
if(count){
this.window[count] = 0;
}
for(i = 0, sl = s.length; i < sl; i++){
if(s[i] === ''){
continue;
}
for (j = 0, fl = f.length; j < fl; j++){
temp = s[i] + '';
repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0];
s[i] = (temp).split(f[j]).join(repl);
if(count && s[i] !== temp){
this.window[count] += (temp.length-s[i].length) / f[j].length;
}
}
}
return sa ? s : s[0];
},
/** /**
* A check to make sure we have something to wrap our notices with * A check to make sure we have something to wrap our notices with
* @private * @private
@ -387,3 +343,11 @@
} }
})(jQuery); })(jQuery);
// For Emacs:
// Local Variables:
// tab-width: 2
// indent-tabs-mode: t
// End:
// vi: ts=2:noet:sw=2