richer_text 0.9.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 03e9732ed2320f56a2c30cbcd6af7614b6840b601aab70d790c96e6e8412babf
4
- data.tar.gz: 4413b9240e46d0153dff22c7b4dd7161a555f572ada62b69159f0c267ae7b0b4
3
+ metadata.gz: b0896d20faa3ab1fcf20e72e0be2fe6902bf2831b8f21bc5d006f6bbac0d4aad
4
+ data.tar.gz: e0b592625c14d7c867087b29129b4bf711e01675eb8e1187a6aa4114fab9eb48
5
5
  SHA512:
6
- metadata.gz: 39f20dfc3cecd2f74f4cc4d01b396d9678ceeed635ff4dc2a35bc62ba0dc8f6361f882dfe1df67b9286d63b1c86fbd6b7e73b729175e8fd3948435eb041a7ade
7
- data.tar.gz: 4718871930d84edd4de392d9ea2d321f6a04782e5f0c774906e468e8c70ecac6ea9c78fb4ed92dcf7aa8598fea600dea3d13a117beef8287d5b709a8547d2318
6
+ metadata.gz: 3f386bd1e15a650db59353b2627224d5dbdcbcfdaa28f49fe7fde165266cac6d876d618da844a00c7c1d7457468543060437aff4a7c2d41736f7eaf6152d92dc
7
+ data.tar.gz: 364abb9092c4f8bb13959c3dc13291a22b485e8360f12219064ec4bcb73deeff965c4942d5b0320e8d3977ad7bc107a78133649f72a2b02264fa3945a07adc06
@@ -0,0 +1,81 @@
1
+ require "oembed"
2
+
3
+ module RicherText
4
+ class OEmbed < ApplicationRecord
5
+ include RicherText::Embeddable
6
+
7
+ PATTERNS = [
8
+ {source: "^http:\\/\\/([^\\.]+\\.)?flickr\\.com\\/(.*?)", options: ""},
9
+ {source: "^https:\\/\\/([^\\.]+\\.)?flickr\\.com\\/(.*?)", options: ""},
10
+ {source: "^http:\\/\\/flic\\.kr\\/(.*?)", options: ""},
11
+ {source: "^https:\\/\\/flic\\.kr\\/(.*?)", options: ""},
12
+ {source: "^https:\\/\\/([^\\.]+\\.)?imgur\\.com\\/gallery\\/(.*?)", options: ""},
13
+ {source: "^http:\\/\\/([^\\.]+\\.)?imgur\\.com\\/gallery\\/(.*?)", options: ""},
14
+ {source: "^http:\\/\\/instagr\\.am\\/p\\/(.*?)", options: ""},
15
+ {source: "^http:\\/\\/instagram\\.com\\/p\\/(.*?)", options: ""},
16
+ {source: "^http:\\/\\/www\\.instagram\\.com\\/p\\/(.*?)", options: ""},
17
+ {source: "^https:\\/\\/instagr\\.am\\/p\\/(.*?)", options: ""},
18
+ {source: "^https:\\/\\/instagram\\.com\\/p\\/(.*?)", options: ""},
19
+ {source: "^https:\\/\\/www\\.instagram\\.com\\/p\\/(.*?)", options: ""},
20
+ {source: "^http:\\/\\/([^\\.]+\\.)?soundcloud\\.com\\/(.*?)", options: ""},
21
+ {source: "^https:\\/\\/([^\\.]+\\.)?soundcloud\\.com\\/(.*?)", options: ""},
22
+ {source: "^http:\\/\\/open\\.spotify\\.com\\/(.*?)", options: ""},
23
+ {source: "^https:\\/\\/open\\.spotify\\.com\\/(.*?)", options: ""},
24
+ {source: "^http:\\/\\/play\\.spotify\\.com\\/(.*?)", options: ""},
25
+ {source: "^https:\\/\\/play\\.spotify\\.com\\/(.*?)", options: ""},
26
+ {source: "^spotify\\:(.*?)", options: ""},
27
+ {source: "^https:\\/\\/([^\\.]+\\.)?twitter\\.com\\/(.*?)\\/status\\/(.*?)", options: ""},
28
+ {source: "^http:\\/\\/([^\\.]+\\.)?vimeo\\.com\\/(.*?)", options: ""},
29
+ {source: "^https:\\/\\/([^\\.]+\\.)?vimeo\\.com\\/(.*?)", options: ""},
30
+ {source: "^http:\\/\\/([^\\.]+\\.)?youtube\\.com\\/(.*?)", options: ""},
31
+ {source: "^https:\\/\\/([^\\.]+\\.)?youtube\\.com\\/(.*?)", options: ""},
32
+ {source: "^http:\\/\\/([^\\.]+\\.)?youtu\\.be\\/(.*?)", options: ""},
33
+ {source: "^https:\\/\\/([^\\.]+\\.)?youtu\\.be\\/(.*?)", options: ""}
34
+ ]
35
+
36
+ def self.from_url(url)
37
+ find_by!(url: url)
38
+ rescue ActiveRecord::RecordNotFound
39
+ resource = ::OEmbed::Providers.get(url)
40
+ create!(url: url, fields: resource.fields)
41
+ end
42
+
43
+ def self.delegate_fields(*keys)
44
+ keys.each do |key|
45
+ define_method(key) do
46
+ fields[key.to_s]
47
+ end
48
+ end
49
+ end
50
+
51
+ delegate_fields(
52
+ :type,
53
+ :version,
54
+ :title,
55
+ :author_name,
56
+ :author_url,
57
+ :provider_name,
58
+ :provider_url,
59
+ :thumbnail_url,
60
+ :thumbnail_width,
61
+ :thumbnail_height,
62
+ :height,
63
+ :width,
64
+ :html
65
+ )
66
+
67
+ %w[link photo rich video].each do |embed_type|
68
+ define_method "#{embed_type}?" do
69
+ type == embed_type
70
+ end
71
+ end
72
+
73
+ def to_embeddable_partial_path
74
+ "richer_text/o_embeds/embed"
75
+ end
76
+
77
+ def to_richer_text_editor_partial_path
78
+ "richer_text/o_embeds/richer_text_editor_embed"
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,11 @@
1
+ <% if o_embed.thumbnail_url && !o_embed.html %>
2
+ <div class="embed">
3
+ <%= image_tag o_embed.thumbnail_url %>
4
+ </div>
5
+ <% elsif o_embed.html %>
6
+ <div class="embed">
7
+ <%= o_embed.html.html_safe %>
8
+ </div>
9
+ <% elsif o_embed.provider_name %>
10
+ <%= link_to o_embed.provider_name, o_embed.url %>
11
+ <% end %>
@@ -0,0 +1,11 @@
1
+ <% if o_embed.thumbnail_url %>
2
+ <div class="embed">
3
+ <%= image_tag o_embed.thumbnail_url %>
4
+ </div>
5
+ <% elsif o_embed.html %>
6
+ <div class="embed">
7
+ <%= o_embed.html.html_safe %>
8
+ </div>
9
+ <% elsif o_embed.provider_name %>
10
+ <%= link_to o_embed.provider_name, o_embed.url %>
11
+ <% end %>
@@ -0,0 +1,10 @@
1
+ class CreateRicherTextOEmbeds < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :richer_text_o_embeds do |t|
4
+ t.jsonb :fields
5
+ t.string :url
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,27 @@
1
+ module RicherText
2
+ class Embed
3
+ include Rendering
4
+
5
+ def self.find(sgid)
6
+ @embed = GlobalID::Locator.locate_signed(sgid, for: "embeddable")
7
+ new(@embed) if @embed
8
+ end
9
+
10
+ attr_reader :embed
11
+
12
+ def initialize(embed)
13
+ @embed = embed
14
+ end
15
+
16
+ def object
17
+ @embed
18
+ end
19
+
20
+ delegate :to_richer_text_editor_partial_path, to: :@embed
21
+ delegate :model_name, to: :@embed
22
+
23
+ def html
24
+ render partial: to_richer_text_editor_partial_path, object: object, as: model_name.element
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ module RicherText
2
+ module Embeddable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ def embeddable_sgid
7
+ to_sgid(expires_in: nil, for: "embeddable").to_s
8
+ end
9
+
10
+ def to_embeddable_partial_path
11
+ to_partial_path
12
+ end
13
+
14
+ def to_richer_text_editor_partial_path
15
+ to_partial_path
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,4 +1,5 @@
1
1
  require "rails"
2
+ require "oembed"
2
3
 
3
4
  module RicherText
4
5
  class Engine < ::Rails::Engine
@@ -15,5 +16,13 @@ module RicherText
15
16
  helper RicherText::TagHelper
16
17
  end
17
18
  end
19
+
20
+ config.after_initialize do
21
+ ::OEmbed::Providers.register_all
22
+ ::OEmbed::Providers.register_fallback(
23
+ ::OEmbed::ProviderDiscovery,
24
+ ::OEmbed::Providers::Noembed
25
+ )
26
+ end
18
27
  end
19
28
  end
@@ -57,6 +57,10 @@ module RicherText
57
57
  "<p style='#{node.style}'>#{visit_children(node).join}</p>"
58
58
  end
59
59
 
60
+ def visit_richer_text_embed(node)
61
+ node.html
62
+ end
63
+
60
64
  def visit_list_item(node)
61
65
  "<li>#{visit_children(node).join}</li>"
62
66
  end
@@ -78,7 +82,7 @@ module RicherText
78
82
  end
79
83
 
80
84
  def visit_image(node)
81
- "<img src='#{node.src}' />"
85
+ "<img src='#{node.src}' width='#{node.width}' />"
82
86
  end
83
87
 
84
88
  def visit_text(node, marks)
@@ -1,6 +1,7 @@
1
1
  module RicherText
2
2
  class Node
3
3
  attr_reader :json, :attrs, :children, :type
4
+ include RicherText::Rendering
4
5
 
5
6
  STYLES = {
6
7
  "textAlign" => "text-align",
@@ -8,6 +8,10 @@ module RicherText
8
8
  def signed_id
9
9
  @signed_id = attrs['signedId']
10
10
  end
11
+
12
+ def width
13
+ attrs['width']
14
+ end
11
15
  end
12
16
  end
13
17
  end
@@ -0,0 +1,19 @@
1
+ module RicherText
2
+ module Nodes
3
+ class RicherTextEmbed < ::RicherText::Node
4
+ def sgid
5
+ attrs["sgid"]
6
+ end
7
+
8
+ def html
9
+ render partial: embeddable.to_embeddable_partial_path, object: embeddable, as: embeddable.model_name.element
10
+ rescue ActiveRecord::RecordNotFound, NoMethodError
11
+ "" # TODO: handle this better
12
+ end
13
+
14
+ def embeddable
15
+ @embeddable ||= GlobalID::Locator.locate_signed(sgid, for: "embeddable")
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,13 +1,23 @@
1
+ require "active_support/concern"
2
+ require "active_support/core_ext/module/attribute_accessors_per_thread"
3
+
1
4
  module RicherText
2
5
  module Rendering
3
- private
6
+ extend ActiveSupport::Concern
4
7
 
5
- def render(*args, &block)
6
- action_controller_renderer.render(*args, &block)
8
+ included do
9
+ thread_cattr_accessor :renderer, instance_accessor: false
10
+ delegate :render, to: :class
7
11
  end
8
12
 
9
- def action_controller_renderer
10
- ActionController::Base.renderer
13
+ class_methods do
14
+ def action_controller_renderer
15
+ @action_controller_renderer ||= Class.new(ActionController::Base).renderer
16
+ end
17
+
18
+ def render(*args, &block)
19
+ (renderer || action_controller_renderer).render_to_string(*args, &block)
20
+ end
11
21
  end
12
22
  end
13
23
  end
@@ -1,3 +1,3 @@
1
1
  module RicherText
2
- VERSION = "0.9.0"
2
+ VERSION = "0.11.0"
3
3
  end
data/lib/richer_text.rb CHANGED
@@ -14,6 +14,9 @@ module RicherText
14
14
  autoload :Serialization
15
15
  autoload :TagHelper
16
16
 
17
+ autoload :Embed
18
+ autoload :Embeddable
19
+
17
20
  autoload :Node
18
21
  autoload :Mark
19
22
  autoload :HTMLVisitor
@@ -36,6 +39,7 @@ module RicherText
36
39
  autoload :Mention
37
40
  autoload :OrderedList
38
41
  autoload :Paragraph
42
+ autoload :RicherTextEmbed
39
43
  autoload :Text
40
44
  autoload :Table
41
45
  autoload :TableCell
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: richer_text
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrea Fomera
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-22 00:00:00.000000000 Z
11
+ date: 2023-09-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 7.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: ruby-oembed
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  description:
28
42
  email:
29
43
  - afomera@hey.com
@@ -44,16 +58,22 @@ files:
44
58
  - app/mailers/richer_text/application_mailer.rb
45
59
  - app/models/richer_text/application_record.rb
46
60
  - app/models/richer_text/json_text.rb
61
+ - app/models/richer_text/o_embed.rb
47
62
  - app/models/richer_text/rich_text.rb
48
63
  - app/views/layouts/richer_text/application.html.erb
49
64
  - app/views/richer_text/contents/_content.html.erb
65
+ - app/views/richer_text/o_embeds/_embed.html.erb
66
+ - app/views/richer_text/o_embeds/_richer_text_editor_embed.html.erb
50
67
  - config/routes.rb
51
68
  - db/migrate/20230107020316_create_richer_text_rich_texts.rb
52
69
  - db/migrate/20230916224959_create_richer_text_json_texts.rb
70
+ - db/migrate/20230926034114_create_richer_text_o_embeds.rb
53
71
  - lib/generators/richer_text/install/install_generator.rb
54
72
  - lib/richer_text.rb
55
73
  - lib/richer_text/attribute.rb
56
74
  - lib/richer_text/content.rb
75
+ - lib/richer_text/embed.rb
76
+ - lib/richer_text/embeddable.rb
57
77
  - lib/richer_text/engine.rb
58
78
  - lib/richer_text/fragment.rb
59
79
  - lib/richer_text/html_visitor.rb
@@ -74,6 +94,7 @@ files:
74
94
  - lib/richer_text/nodes/mention.rb
75
95
  - lib/richer_text/nodes/ordered_list.rb
76
96
  - lib/richer_text/nodes/paragraph.rb
97
+ - lib/richer_text/nodes/richer_text_embed.rb
77
98
  - lib/richer_text/nodes/table.rb
78
99
  - lib/richer_text/nodes/table_cell.rb
79
100
  - lib/richer_text/nodes/table_header.rb