Imperavi Redactor widget breaking

I’ve found that all Imperavi Redactor widgets can’t parse this code correct:




<p>$'any string</p>

<p>test</p>



Result:




<p>

	test

</p>

any string{replace2}



Sequence $’ is breaking widgets. Is there any ideas why does this could happen? This sequence meeting in most of JavaScript RegExps, so it’s pretty important.

I suppose it’s an issue with Redactor and not with the widgets for Yii, but informing community about it, and maybe we can find out how to fix it.

[html]$& #39;[/html] Is breaking too. (&# without space, written this way only because forum convert it to ').


$&

This sequence looks broken too.

Try to use & #36; (remove space) instead of $ - does it help?

nope. I even tried: & #36; & #39;

This works so far




<p>$ 'any string</p>

<p>test</p>



Yep, we can find all $’ and $& (and maybe another ones) sequences in all texts and replace them with $ ’ and $ &. But it’s kinda hacky. Bizley, have you replicated this issue too?

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.

Thank you for a great detailed dive into this issue!

Confirming, it’s working for me too.

Your fix on Pastebin because forum converting chars.

I’ve sent the email to support@imperavi.com about this.

Redactor 10.0.8 has been released on March 10 and on “fixed” list there is this mysterious note “’$’ being deleted from the text when part of a string of these symbols” so maybe they fixed it.

Now we have to wait for Samdark to update our widget.

Thats a great news! Thank you for the information!