From f412ab2c9a624ff7fc2da6f87af57f93877c19e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Mon, 26 Jul 2021 01:07:40 +0200 Subject: [PATCH] Add CKEditor support for ActiveStorage ActiveStorage support was added to CKEditor in version 5.1.0. However, we can't upgrade to version 5.0.0 or later because it only supports loading CKEditor via CDN. So we're copying the code related to ActiveStorage instead. I tried to move it to the `vendor/` folder, but couldn't find a way to load it from there and if I found one I wouldn't be sure it'd work on production environments. --- .rubocop.yml | 1 + lib/ckeditor/backend/active_storage.rb | 73 ++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 lib/ckeditor/backend/active_storage.rb diff --git a/.rubocop.yml b/.rubocop.yml index 0f92631ba..483b38bbe 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -8,6 +8,7 @@ AllCops: DisplayStyleGuide: true Exclude: - "db/schema.rb" + - "lib/ckeditor/backend/active_storage.rb" DisabledByDefault: true Bundler/DuplicatedGem: diff --git a/lib/ckeditor/backend/active_storage.rb b/lib/ckeditor/backend/active_storage.rb new file mode 100644 index 000000000..710db0aed --- /dev/null +++ b/lib/ckeditor/backend/active_storage.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +# Code copied from the ckeditor gem: +# https://github.com/galetahub/ckeditor/pull/853 +module Ckeditor + module Backend + module ActiveStorage + def self.included(base) + base.send(:include, Rails.application.routes.url_helpers) + base.send(:include, InstanceMethods) + base.send(:extend, ClassMethods) + end + + module ClassMethods + def self.extended(base) + base.class_eval do + before_save :apply_data + validate do + if data.nil? || file.nil? + errors.add(:data, :not_data_present, message: "data must be present") + end + end + end + end + end + + module InstanceMethods + def url + rails_blob_path(self.storage_data, only_path: true) + end + + def path + rails_blob_path(self.storage_data, only_path: true) + end + + def styles + end + + def content_type + self.storage_data.content_type + end + + def content_type=(_content_type) + self.storage_data.content_type = _content_type + end + + protected + + def file + @file ||= storage_data + end + + def blob + @blob ||= ::ActiveStorage::Blob.find(file.attachment.blob_id) + end + + def apply_data + if data.is_a?(Ckeditor::Http::QqFile) + storage_data.attach(io: data, filename: data.original_filename) + else + storage_data.attach(data) + end + + self.data_file_name = storage_data.blob.filename + self.data_content_type = storage_data.blob.content_type + self.data_file_size = storage_data.blob.byte_size + end + end + end + + autoload :ActiveStorage, "ckeditor/backend/active_storage" + end +end