I’ve managed to create a temporary fix for this. I will let Imperavi know about it as well.
I’m working on Yii1 but redactor.js file should be the same in both cases.
It goes like that - this is the part that cleans the html code from source:
clean: function()
{
return {
onSet: function(html)
{
html = this.clean.savePreCode(html);
// convert script tag
html = html.replace(/<script(.*?[^>]?)>([\w\W]*?)<\/script>/gi, '<pre class="redactor-script-tag" style="display: none;" $1>$2</pre>');
// replace dollar sign to entity
html = html.replace(/\$/g, '$');
html = html.replace(/”/g, '"');
html = html.replace(/‘/g, '\'');
html = html.replace(/’/g, '\'');
if (this.opts.replaceDivs) html = this.clean.replaceDivs(html);
if (this.opts.linebreaks) html = this.clean.replaceParagraphsToBr(html);
// save form tag
html = this.clean.saveFormTags(html);
// convert font tag to span
var $div = $('<div>');
$div.html(html);
var fonts = $div.find('font[style]');
if (fonts.length !== 0)
{
fonts.replaceWith(function()
{
var $el = $(this);
var $span = $('<span>').attr('style', $el.attr('style'));
return $span.append($el.contents());
});
html = $div.html();
}
$div.remove();
// remove font tag
html = html.replace(/<font(.*?[^<])>/gi, '');
html = html.replace(/<\/font>/gi, '');
// tidy html
html = this.tidy.load(html);
// paragraphize
if (this.opts.paragraphize) html = this.paragraphize.load(html);
// verified
html = this.clean.setVerified(html);
// convert inline tags
html = this.clean.convertInline(html);
return html;
Forum editor is automatically replacing html entities so it’s not 1 to 1 code.
Anyway - $ is replaced with entity here (had to add space to stop autoreplace)
html = html.replace(/\$/g, '& #36;');
But later on it’s being replaced back here:
html = this.tidy.load(html);
The problem starts here
if (this.opts.paragraphize) html = this.paragraphize.load(html);
this.paragraphize.load is cleaning the code and modifies break line characters. When each paragraph is being restored after cleaning here:
restoreSafes: function(html)
{
$.each(this.paragraphize.safes, function(i,s)
{
html = html.replace('{replace' + i + '}', s);
});
return html;
},
It finds $ sign that is not escaped. As stated here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace the replacement string can include the following special replacement patterns:
Pattern Inserts
$$ Inserts a "$".
$& Inserts the matched substring.
$` Inserts the portion of the string that precedes the matched substring.
$' Inserts the portion of the string that follows the matched substring.
$n or $nn Where n or nn are decimal digits, inserts the nth parenthesized submatch string, provided the first argument was a RegExp object.
So our $’ is right here.
The quick fix is this for example:
restoreSafes: function(html)
{
$.each(this.paragraphize.safes, function(i,s)
{
if (s !== undefined) s = s.replace(/\$/g, '& #36;');
html = html.replace('{replace' + i + '}', s);
});
return html;
},
I’m replacing $ with entity again here (remove space of course). I’m not sure if this not breaks anything else but it seems to work.