diff --git a/app/models/concerns/tiny_mce_images.rb b/app/models/concerns/tiny_mce_images.rb index 0d1373d25..7871c03f4 100644 --- a/app/models/concerns/tiny_mce_images.rb +++ b/app/models/concerns/tiny_mce_images.rb @@ -9,6 +9,8 @@ module TinyMceImages class_name: :TinyMceAsset, dependent: :destroy + before_save :clean_tiny_mce_image_urls + def prepare_for_report(field) description = self[field] tiny_mce_assets.each do |tm_asset| @@ -34,5 +36,34 @@ module TinyMceImages def tinymce_render(field) TinyMceAsset.generate_url(self[field]) end + + # Takes array of old/new TinyMCE asset ID pairs + # and updates references in assosiated object's description + def reassign_tiny_mce_image_references(images = []) + object_field = Extends::RICH_TEXT_FIELD_MAPPINGS[self.class.name] + parsed_description = Nokogiri::HTML(read_attribute(object_field)) + images.each do |image| + old_id = image[0] + new_id = image[1] + image = parsed_description.at_css("img[data-mce-token=\"#{Base62.encode(old_id)}\"]") + image['data-mce-token'] = Base62.encode(new_id) + end + update(object_field => parsed_description.to_html) + end + + private + + def clean_tiny_mce_image_urls + object_field = Extends::RICH_TEXT_FIELD_MAPPINGS[self.class.name] + return unless changed.include?(object_field.to_s) + image_changed = false + parsed_description = Nokogiri::HTML(read_attribute(object_field)) + parsed_description.css('img[data-mce-token]').each do |image| + image['src'] = '' + image['class'] = 'img-responsive' + image_changed = true + end + self[object_field] = parsed_description.to_html if image_changed + end end end diff --git a/app/models/protocol.rb b/app/models/protocol.rb index fba93b57d..c70fb7250 100644 --- a/app/models/protocol.rb +++ b/app/models/protocol.rb @@ -347,7 +347,7 @@ class Protocol < ApplicationRecord step2.tiny_mce_assets << tiny_img2 cloned_img_ids << [tiny_img.id, tiny_img2.id] end - TinyMceAsset.reload_images(cloned_img_ids) + step2.reassign_tiny_mce_image_references(cloned_img_ids) end # Call clone helper diff --git a/app/models/tiny_mce_asset.rb b/app/models/tiny_mce_asset.rb index 0e2dfec7c..a6130a7b3 100644 --- a/app/models/tiny_mce_asset.rb +++ b/app/models/tiny_mce_asset.rb @@ -6,7 +6,6 @@ class TinyMceAsset < ApplicationRecord before_create :set_reference, optional: true after_create :update_estimated_size, :self_destruct after_destroy :release_team_space - after_save :update_description belongs_to :team, inverse_of: :tiny_mce_assets, optional: true belongs_to :step, inverse_of: :tiny_mce_assets, touch: true, optional: true @@ -49,30 +48,6 @@ class TinyMceAsset < ApplicationRecord Rails.logger.error e.message end - def self.reload_images(images = []) - images.each do |image| - old_id = image.class == Array ? image[0] : image - new_id = image.class == Array ? image[1] : image - image_to_update = find_by_id(new_id) - next unless image_to_update - - object_field = data_fields[image_to_update.object_type] - next unless image_to_update.object && image_to_update.object[object_field] - - old_description = Nokogiri::HTML(image_to_update.object[object_field]) - description_image = old_description.css( - "img[data-mce-token=\"#{Base62.encode(old_id)}\"]" - ) - next if description_image.empty? - - description_image.attr('src').value = '' - description_image.attr('data-mce-token').value = Base62.encode(new_id) - description_image[0]['class'] = 'img-responsive' - new_description = old_description.css('body').inner_html.to_s - image_to_update.object.update(object_field => new_description) - end - end - def self.generate_url(description) description = Nokogiri::HTML(description) tm_assets = description.css('img') @@ -129,15 +104,6 @@ class TinyMceAsset < ApplicationRecord asset.destroy if asset && !asset.saved end - def self.data_fields - { - 'Step' => :description, - 'ResultText' => :text, - 'Protocol' => :description, - 'MyModule' => :description - } - end - def self.update_old_tinymce(description) description.scan(/\[~tiny_mce_id:(\w+)\]/).flatten.each do |token| old_format = /\[~tiny_mce_id:#{token}\]/ @@ -165,10 +131,6 @@ class TinyMceAsset < ApplicationRecord private - def update_description - TinyMceAsset.reload_images([id]) if object - end - def self_destruct TinyMceAsset.delay(queue: :assets, run_at: 1.days.from_now).delete_unsaved_image(id) end diff --git a/config/initializers/extends.rb b/config/initializers/extends.rb index 3dce3347e..db7d05d98 100644 --- a/config/initializers/extends.rb +++ b/config/initializers/extends.rb @@ -83,4 +83,10 @@ class Extends # Hash used for mapping file extensions to custom font awesome icon classes, # 'extension' => 'fa class' FILE_FA_ICON_MAPPINGS = {} + + # Mapping of rich text fileds to specific model + RICH_TEXT_FIELD_MAPPINGS = { 'Step' => :description, + 'ResultText' => :text, + 'Protocol' => :description, + 'MyModule' => :description } end diff --git a/spec/models/tiny_mce_asset_spec.rb b/spec/models/tiny_mce_asset_spec.rb index b8a555d2c..331e41b3b 100644 --- a/spec/models/tiny_mce_asset_spec.rb +++ b/spec/models/tiny_mce_asset_spec.rb @@ -32,7 +32,7 @@ describe TinyMceAsset, type: :model do describe 'Methods' do let(:result_text) do create :result_text, - text: '' + text: '' end let(:image) { create :tiny_mce_asset, id: 1 } @@ -54,12 +54,12 @@ describe TinyMceAsset, type: :model do end end - describe '#reload_images' do - it 'change image token in description' do + describe '#reassign_tiny_mce_image_references' do + it 'change image token in rich text field' do new_result_text = result_text TinyMceAsset.update_images(new_result_text, [Base62.encode(image.id)].to_s) create :tiny_mce_asset, id: 2, object: new_result_text - TinyMceAsset.reload_images([[1, 2]]) + new_result_text.reassign_tiny_mce_image_references([[1, 2]]) expect(ResultText.find(new_result_text.id).text).to include 'data-mce-token="2"' end end