This commit is contained in:
2025-11-07 13:34:32 -08:00
commit 1e8c5a972b
436 changed files with 11000 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
module ActionText
module HasMarkdown
extend ActiveSupport::Concern
class_methods do
def has_markdown(name, strict_loading: strict_loading_by_default)
class_eval <<-CODE, __FILE__, __LINE__ + 1
def #{name}
markdown_#{name} || build_markdown_#{name}
end
def #{name}?
markdown_#{name}.present?
end
def #{name}=(content)
self.#{name}.content = content
end
CODE
has_one :"markdown_#{name}", -> { where(name: name) },
class_name: "ActionText::Markdown", as: :record, inverse_of: :record, autosave: true, dependent: :destroy,
strict_loading: strict_loading
scope :"with_markdown_#{name}", -> { includes("markdown_#{name}") }
scope :"with_markdown_#{name}_and_embeds", -> { includes("markdown_#{name}": { embeds_attachments: :blob }) }
end
end
def safe_markdown_attribute(name)
if self.class.reflect_on_association("markdown_#{name}")&.klass == ActionText::Markdown
public_send(name)
end
end
end
end
ActiveSupport.on_load :active_record do
include ActionText::HasMarkdown
end

View File

@@ -0,0 +1,42 @@
module ActionText
class Markdown < Record
DEFAULT_RENDERER_OPTIONS = {
filter_html: false
}
DEFAULT_MARKDOWN_EXTENSIONS = {
autolink: true,
highlight: true,
no_intra_emphasis: true,
fenced_code_blocks: true,
lax_spacing: true,
strikethrough: true,
tables: true
}
mattr_accessor :renderer, default: Redcarpet::Markdown.new(
Redcarpet::Render::HTML.new(DEFAULT_RENDERER_OPTIONS), DEFAULT_MARKDOWN_EXTENSIONS)
belongs_to :record, polymorphic: true, touch: true
def to_html
(renderer.try(:call) || renderer).render(content).html_safe
end
end
end
module ActionText::Markdown::Uploads
extend ActiveSupport::Concern
included do
has_many_attached :uploads, dependent: :destroy
end
end
ActiveSupport.on_load :active_storage_attachment do
class ActionText::Markdown
include ActionText::Markdown::Uploads
end
end
ActiveSupport.run_load_hooks :action_text_markdown, ActionText::Markdown

View File

@@ -0,0 +1,39 @@
module ActionText
module TagHelper
def markdown_area(record, name, value: nil, **options)
field_name = "#{record.class.model_name.param_key}[#{name}]"
value = record.safe_markdown_attribute(name).content.to_s if value.nil?
data = options.delete(:data) || {}
data.reverse_merge! \
uploads_url: action_text_markdown_uploads_url(record_gid: record.to_signed_global_id.to_s, attribute_name: name, format: "json")
tag.house_md value, name: field_name, data: data, **options
end
def house_toolbar(**options, &block)
tag.house_md_toolbar(**options, &block)
end
def house_toolbar_button(action, **options, &block)
tag.button title: action.to_s.humanize, data: { "house-md-action": action }, **options, &block
end
def house_toolbar_file_upload_button(name: "upload", title: "Upload File", **options, &block)
tag.label title: title, **options do
safe_join [
file_field_tag(name, data: { "house-md-toolbar-file-picker": true }, style: "display: none;"),
capture(&block)
]
end
end
end
end
module ActionView::Helpers
class FormBuilder
def markdown_area(method, **options)
@template.markdown_area(@object, method, **options)
end
end
end

View File

@@ -0,0 +1,32 @@
module ActiveStorage::Sluggable
extend ActiveSupport::Concern
included do
before_create :set_slug
end
def slug_url(host: ActiveStorage::Current.host)
Rails.application.routes.url_helpers.action_text_markdown_upload_url(slug, host: host)
end
private
def set_slug
self.slug = "#{slug_basename}-#{SecureRandom.alphanumeric(6)}.#{slug_extension}"
end
def slug_basename
File.basename(slug_filename, ".*").parameterize
end
def slug_extension
File.extname(slug_filename).delete(".").parameterize
end
def slug_filename
slug.presence || filename.to_s
end
end
ActiveSupport.on_load :active_storage_attachment do
ActiveStorage::Attachment.include ActiveStorage::Sluggable
end