taqueci / redmine_wysiwyg_editor

Redmine WYSIWYG Editor plugin
GNU General Public License v2.0
114 stars 27 forks source link

Zenedit plugin - Images are gone after switching editors #161

Open albenik85 opened 1 year ago

albenik85 commented 1 year ago

After adding an image in the normal textile editor inside the Wiki, it looks as follows:

!name_of_image.png!

When I switch to the visual editor, there is an empty space where the image should be. After saving the article, the image is gone in the Wiki. After switching back to edit mode in the textile editor, it looks as follows:

!https://url_of_redmine/projects/project_name/wiki/name_of_image.png!

Then I have to change the entry again to !name_of_image.png! in order to bring the image back

pr-dtakac commented 1 year ago

Hi @taqueci, I had the same problem with images. I know nothing about Ruby or Redmine. I tried to analyse it and it seems that problem is in returned data from preview endpoint. Here is my attempt to solve it in javascript. Can you review it and maybe do some similar fix in next release? Thanks a lot.

--- a/assets/javascripts/redmine_wysiwyg_editor.js
+++ b/assets/javascripts/redmine_wysiwyg_editor.js
@@ -750,7 +750,12 @@ RedmineWysiwygEditor.prototype._setVisualContent = function() {
     url: self._previewUrl,
     data: previewData(self._jstEditorTextArea),
     success: function(data) {
-      self._editor.setContent(htmlContent(data));
+      var markup = htmlContent(data);
+      // when mode is switched to visual editor, attachment images are not loading,
+      // if they are in short form (like !image.jpg!), after any changes in visual editor
+      // images src value is broken - we'll try to fix it
+      markup = self._fixAttachmentImagesInContent(markup);
+      self._editor.setContent(markup);
     }
   });
 };
@@ -1466,7 +1471,10 @@ RedmineWysiwygEditor.prototype._setPreview = function() {
     url: self._previewUrl,
     data: previewData(self._jstEditorTextArea),
     success: function(data) {
-      self._preview.html(data);
+      // when mode is switched to preview, attachment images are not loading,
+      // if they are in short form (like !image.jpg!) - we'll try to fix it
+      var markup = self._fixAttachmentImagesInContent(data);
+      self._preview.html(markup);
     }
   });
 };
@@ -1604,5 +1612,46 @@ RedmineWysiwygEditor.prototype._setChanged = function() {
   self._jstEditorTextArea.data('changed', 'changed');
 };

+RedmineWysiwygEditor.prototype._escapeRegExp = function(string) {
+  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
+};
+
+RedmineWysiwygEditor.prototype._escapeReplacement = function(string) {
+  return string.replace(/\$/g, '$$$$');
+};
+
+RedmineWysiwygEditor.prototype._fixAttachmentImagesInContent = function(content) {
+  var self = this;
+
+  var attachment = Object.keys(self._attachment);
+
+  var attachmentImages = attachment.filter(function(name) {
+    return RedmineWysiwygEditor._isImageFile(name);
+  });
+
+  $.each(attachmentImages, function( index, image ) {
+    var src = 'src="' + image + '"';
+    var encodedSrc = 'src="' + encodeURIComponent(image) + '"';
+    var plainSrcFound = content.search(src) !== -1;
+    var encodedSrcFound = content.search(encodedSrc) !== -1;
+    if (plainSrcFound || encodedSrcFound) {
+      var id = self._attachment[image];
+      var url = self._prefix +
+          ['attachments', 'download', id, encodeURIComponent(image)].join('/');
+      var stringToEscape = plainSrcFound ? src : encodedSrc;
+      // regex magic - see https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
+      var safeSrc = self._escapeRegExp(stringToEscape);
+      var replacement = src.replace(image, url);
+      var safeReplacement = self._escapeReplacement(replacement);
+
+      content = content.replace(
+          new RegExp(safeSrc, 'g'),
+          self._escapeReplacement(safeReplacement),
+      );
+    }
+  });
+  return content;
+}
+
 return RedmineWysiwygEditor;
 }));
taqueci commented 1 year ago

Hi @pr-dtakac Thank you for the information.

Hi @albenik85 Could you please tell me your environment information? (Administration » Information)

albenik85 commented 1 year ago

Hi @taqueci

here are the requested information:

Environment: Redmine version 5.0.2.stable Ruby version 2.7.2-p137 (2020-10-01) [x86_64-linux] Rails version 6.1.6 Environment production Database adapter Mysql2 Mailer queue ActiveJob::QueueAdapters::AsyncAdapter Mailer delivery smtp Redmine settings: Redmine theme Purplemine2-master (includes JavaScript) SCM: Git 2.25.1 Filesystem
Redmine plugins: additional_tags 1.0.6 additionals 3.0.7 mega_calendar 1.9.1 redmine_add_absolute_time 0.0.1 redmine_agile 1.6.4 redmine_automation 3.0.7 redmine_checklists 3.1.21 redmine_contacts 4.3.6 redmine_contacts_helpdesk 4.1.13 redmine_contacts_invoices 4.2.6 redmine_crm_mailchimp 1.0.4 redmine_db 3.0.7 redmine_devops 3.0.7 redmine_dmsf 3.0.7 redmine_drawio 1.4.1 redmine_finance 2.1.8 redmine_hide_sidebar 4.0.0 redmine_hrm 3.0.7 redmine_issue_dynamic_edit 0.8.1 redmine_issue_view_columns 2.0.2 redmine_lightbox 1.0.1 redmine_messenger 1.0.13 redmine_products 2.1.5 redmine_questions 1.0.3 redmine_ref_issues 1.0.2 redmine_reporter 2.0.2 redmine_reporting 3.0.7 redmine_shared_api 0.0.9 redmine_wiki_guide 3.0.7 redmine_wysiwyg_editor 0.27.0 redmine_x_assets 2.1.0 redmine_x_client 1.1.0 redmine_x_gantt 2.1.0 redmine_xapian 3.0.2 redmine_zenedit 2.0.3

taqueci commented 1 year ago

Note to self

Plugins installed on both albenik85's environment and pr-dtakac's one:

nedprofit commented 1 year ago

@taqueci, I had a similar problem and it was solved by disabling the zenedit plugin. Maybe this will help you.

pr-dtakac commented 1 year ago

Edit: I can confirm that zenedit is somehow related to this problem. :) When I uninstall zenedit plugin, data returned from preview endpoint

$.ajax({
    type: 'POST',
    url: self._previewUrl,
...

now contains correctly transformed img path.

taqueci commented 1 year ago

Thank you for your information. The issue is reproduced on my environment:

Environment:
  Redmine version                5.0.0.stable
  Ruby version                   3.1.2-p20 (2022-04-12) [x86_64-linux-musl]
  Rails version                  6.1.4.7
  Environment                    production
  Database adapter               PostgreSQL
  Mailer queue                   ActiveJob::QueueAdapters::AsyncAdapter
  Mailer delivery                smtp
Redmine settings:
  Redmine theme                  Default
SCM:
  Subversion                     1.14.2
  Mercurial                      5.9.3
  Bazaar                         3.2.1
  Git                            2.34.1
  Filesystem                     
Redmine plugins:
  redmine_wysiwyg_editor         0.27.1
  redmine_zenedit                2.0.3

Zenedit uses its own preview method /zen_preview, but sets default preview URL with /preview/text even though Zenedit does not use /preview/text.

Without Zenedit:

<script>
//<![CDATA[
var wikiToolbar = new jsToolBar(document.getElementById('issue_description'));
wikiToolbar.setHelpLink('/help/ja/wiki_syntax_textile.html');
wikiToolbar.setPreviewUrl('/issues/preview?issue_id=1&project_id=foo');
wikiToolbar.draw();
//]]>
</script>

With Zenedit:

<script src="/plugin_assets/redmine_zenedit/javascripts/zenedit.js?1670657343"></script>
<link rel="stylesheet" media="screen" href="/plugin_assets/redmine_zenedit/stylesheets/zenedit.css?1670657343" />
<script>
//<![CDATA[
var wikiToolbar = new jsToolBar(document.getElementById('issue_description'));
wikiToolbar.setHelpLink('/help/ja/wiki_syntax_textile.html');
wikiToolbar.setPreviewUrl('/preview/text');
wikiToolbar.draw();
//]]>
</script>
<script>
//<![CDATA[
new jsZenEdit(document.getElementById('issue_description'), {"title":"Zen","placeholder":"Leave a comment","previewURL":"/zen_preview?id=1","usersAutoCompleteURL":"","issuesAutoCompleteURL":"","enableUserMentions":false,"enableIssueMentions":false});
//]]>
</script>

I hope this is fixed by Zenedit.

jcatrysse commented 1 year ago

I have quite some good contacts with those (very nice) people of RedmineUP. If someone could tell me what should be changed in the code on their side, I could propose a patch... Can someone provide a patch?

m0lchy commented 1 month ago

Hi together,

I've got the issue too. While copying an image it adds the whole URL of redmine to the path (redmine.company.com/xxxx.png). Is there a fix / workaround?

@pr-dtakac - looks like that the fix isnt working for me

Thanks alot!