thredded 0.10.1 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +30 -10
  3. data/app/assets/images/favicons/README.md +3 -0
  4. data/app/assets/images/favicons/amazon.png +0 -0
  5. data/app/assets/images/favicons/github.png +0 -0
  6. data/app/assets/images/favicons/google_branding/logo_calendar_128px.png +0 -0
  7. data/app/assets/images/favicons/google_branding/logo_docs_48px.png +0 -0
  8. data/app/assets/images/favicons/google_branding/logo_drive_48px.png +0 -0
  9. data/app/assets/images/favicons/google_branding/logo_forms_48px.png +0 -0
  10. data/app/assets/images/favicons/google_branding/logo_sheets_48px.png +0 -0
  11. data/app/assets/images/favicons/google_branding/logo_slides_48px.png +0 -0
  12. data/app/assets/images/favicons/stackexchange.png +0 -0
  13. data/app/assets/images/favicons/twitter.png +0 -0
  14. data/app/assets/images/favicons/wikipedia.png +0 -0
  15. data/app/assets/javascripts/thredded/components/user_preferences_form.es6 +16 -1
  16. data/app/assets/stylesheets/thredded/_email.scss +52 -0
  17. data/app/assets/stylesheets/thredded/_thredded.scss +1 -0
  18. data/app/assets/stylesheets/thredded/base/_grid.scss +14 -1
  19. data/app/assets/stylesheets/thredded/base/_typography.scss +4 -0
  20. data/app/assets/stylesheets/thredded/base/_variables.scss +24 -1
  21. data/app/assets/stylesheets/thredded/components/_main-section.scss +6 -0
  22. data/app/assets/stylesheets/thredded/components/_messageboard.scss +4 -1
  23. data/app/assets/stylesheets/thredded/components/_onebox.scss +284 -0
  24. data/app/assets/stylesheets/thredded/components/_post.scss +10 -6
  25. data/app/assets/stylesheets/thredded/components/_topic-header.scss +1 -1
  26. data/app/assets/stylesheets/thredded/components/_topics.scss +5 -5
  27. data/app/assets/stylesheets/thredded/layout/_main-navigation.scss +0 -6
  28. data/app/assets/stylesheets/thredded/layout/_moderation.scss +1 -1
  29. data/app/commands/thredded/autofollow_users.rb +56 -0
  30. data/app/controllers/thredded/preferences_controller.rb +2 -0
  31. data/app/forms/thredded/user_preferences_form.rb +18 -0
  32. data/app/helpers/thredded/application_helper.rb +3 -3
  33. data/app/jobs/thredded/auto_follow_and_notify_job.rb +1 -1
  34. data/app/mailer_previews/thredded/base_mailer_preview.rb +19 -8
  35. data/app/mailers/thredded/base_mailer.rb +1 -1
  36. data/app/models/concerns/thredded/post_common.rb +2 -4
  37. data/app/models/thredded/category.rb +4 -0
  38. data/app/models/thredded/messageboard.rb +12 -6
  39. data/app/models/thredded/private_topic.rb +4 -0
  40. data/app/models/thredded/topic.rb +9 -5
  41. data/app/models/thredded/user_messageboard_preference.rb +24 -0
  42. data/app/models/thredded/user_preference.rb +2 -0
  43. data/app/models/thredded/user_topic_follow.rb +1 -1
  44. data/app/notifiers/thredded/email_notifier.rb +1 -15
  45. data/app/views/thredded/messageboard_groups/new.html.erb +15 -13
  46. data/app/views/thredded/messageboards/_form.html.erb +22 -22
  47. data/app/views/thredded/messageboards/edit.html.erb +3 -1
  48. data/app/views/thredded/messageboards/new.html.erb +3 -1
  49. data/app/views/thredded/moderation/_post.html.erb +1 -1
  50. data/app/views/thredded/moderation/_user_post.html.erb +1 -1
  51. data/app/views/thredded/moderation/activity.html.erb +3 -3
  52. data/app/views/thredded/moderation/history.html.erb +2 -2
  53. data/app/views/thredded/moderation/pending.html.erb +2 -2
  54. data/app/views/thredded/moderation/user.html.erb +43 -41
  55. data/app/views/thredded/moderation/users.html.erb +32 -30
  56. data/app/views/thredded/post_mailer/post_notification.html.erb +21 -12
  57. data/app/views/thredded/posts/_content.html.erb +1 -1
  58. data/app/views/thredded/posts_common/_content.html.erb +1 -3
  59. data/app/views/thredded/preferences/_form.html.erb +25 -8
  60. data/app/views/thredded/private_posts/_content.html.erb +1 -1
  61. data/app/views/thredded/private_topic_mailer/message_notification.html.erb +17 -14
  62. data/app/views/thredded/private_topics/edit.html.erb +21 -19
  63. data/app/views/thredded/topics/edit.html.erb +32 -30
  64. data/app/views/thredded/topics/new.html.erb +8 -6
  65. data/app/views/thredded/topics/show.html.erb +1 -1
  66. data/app/views/thredded/users/_post.html.erb +1 -1
  67. data/bin/rubocop +17 -0
  68. data/config/locales/en.yml +13 -1
  69. data/config/locales/es.yml +14 -0
  70. data/config/locales/pl.yml +13 -0
  71. data/config/locales/pt-BR.yml +12 -0
  72. data/config/locales/ru.yml +197 -0
  73. data/db/migrate/20160329231848_create_thredded.rb +2 -8
  74. data/db/upgrade_migrations/20161113161801_upgrade_v0_8_to_v0_9.rb +6 -5
  75. data/db/upgrade_migrations/20170312131417_upgrade_thredded_v0_10_to_v0_11.rb +20 -0
  76. data/lib/generators/thredded/install/templates/initializer.rb +12 -0
  77. data/lib/thredded.rb +12 -3
  78. data/lib/thredded/content_formatter.rb +16 -25
  79. data/lib/thredded/email_transformer.rb +21 -0
  80. data/lib/thredded/email_transformer/base.rb +47 -0
  81. data/lib/thredded/email_transformer/onebox.rb +20 -0
  82. data/lib/thredded/formatting_demo_content.rb +29 -0
  83. data/lib/thredded/html_pipeline/kramdown_filter.rb +5 -1
  84. data/lib/thredded/html_pipeline/onebox_filter.rb +136 -0
  85. data/lib/thredded/version.rb +1 -1
  86. metadata +62 -22
  87. data/app/commands/thredded/autofollow_mentioned_users.rb +0 -31
  88. data/app/commands/thredded/members_marked_notified.rb +0 -19
  89. data/app/models/thredded/post_notification.rb +0 -18
@@ -0,0 +1,197 @@
1
+ ---
2
+ ru:
3
+ thredded:
4
+ content_moderation_states:
5
+ content_blocked_notice: Блокировано
6
+ content_blocked_notice_with_record_html: Блокировано %{moderator} %{time_ago}
7
+ email_notifier:
8
+ by_email: email
9
+ errors:
10
+ login_required: Необходимо зайти на форум.
11
+ not_authorized: Вы не авторизованы.
12
+ private_topic_create_denied: Вы не авторизованы для создания личных сообщений.
13
+ private_topic_not_found: Личное сообщение не найдено.
14
+ form:
15
+ create_btn_submitting: Создаю...
16
+ preview: Обзор
17
+ update: Обновить
18
+ update_btn_submitting: Обновляю...
19
+ messageboard:
20
+ create: Создать форум
21
+ form:
22
+ create_btn_submitting: :thredded.form.create_btn_submitting
23
+ description_label: Описание
24
+ messageboard_group_id_label: Выбрать группу
25
+ no_group: Не группировать
26
+ title_label: Название форума
27
+ update_btn_submitting: :thredded.form.update_btn_submitting
28
+ index:
29
+ page_title: Форумы
30
+ last_updated_by_html: Обновлено %{time_ago} <cite>пользователем %{user}</cite>
31
+ topics_and_posts_counts: "%{topics_count} тем / %{posts_count} постов"
32
+ update: :thredded.form.update
33
+ updated_notice: Форум обновлен
34
+ messageboard_group:
35
+ create: Создать группу форумов
36
+ form:
37
+ create_btn_submitting: :thredded.form.create_btn_submitting
38
+ saved: Группа форумов %{name} создана
39
+ moderation:
40
+ approve_btn: Одобрить
41
+ block_btn: Заблокировать
42
+ pending:
43
+ empty:
44
+ content: Все посты промодерированы.
45
+ title: Хорошая работа!
46
+ post_approved_html: Пост одобрен %{moderator} %{time_ago}.
47
+ post_blocked_html: Пост заблокирован %{moderator} %{time_ago}.
48
+ post_deleted_notice: Этот пост "удален".
49
+ posts_content_changed_since_moderation_html: <a href="%{post_url}">пост</a> был изменен с даты последней модерации.
50
+ Ниже - контент на момент модерации.
51
+ search_users:
52
+ form_label: Поиск пользователей
53
+ form_placeholder: :thredded.moderation.search_users.form_label
54
+ no_results_message: Не найдено пользователей %{query}
55
+ results_message: Пользователи, начинающиеся с ... %{query}
56
+ nav:
57
+ all_messageboards: Все форумы
58
+ edit_messageboard: Редактировать форум
59
+ edit_post: Редактировать пост
60
+ edit_private_topic: :thredded.nav.edit_topic
61
+ edit_topic: Редактировать
62
+ mark_all_read: Пометить все как прочитанное
63
+ moderation: Модерация
64
+ moderation_activity: Активность
65
+ moderation_history: История
66
+ moderation_pending: В ожидании
67
+ moderation_users: Пользователи
68
+ private_topics: Личное
69
+ settings: Уведомления
70
+ null_user_name: Пользователь удален
71
+ posts:
72
+ delete: Удалить пост
73
+ delete_confirm: Вы уверены что хотите удалить пост?
74
+ deleted_notice: Пост был удален.
75
+ edit: :thredded.nav.edit_post
76
+ form:
77
+ content_label: Контент
78
+ create_btn: Ответить
79
+ create_btn_submitting: Отправляется...
80
+ title_label: Добавить пост
81
+ update_btn: Обновить пост
82
+ update_btn_submitting: :thredded.form.update_btn_submitting
83
+ pending_moderation_notice: Ваш пост будет опубликован, когда будет одобрен модератором.
84
+ preferences:
85
+ edit:
86
+ page_title: :thredded.nav.settings
87
+ form:
88
+ auto_follow_topics:
89
+ hint: Автоматически следовать всем новым темам. Изменение этого параметра будет изменить его для всех
90
+ messageboards.
91
+ label: Соблюдайте все новые темы
92
+ follow_topics_on_mention:
93
+ hint: 'Когда кто-то упоминает вас на форуме (например: @sam), Вы будете наблюдать за этой темой.'
94
+ label: Наблюдать за темой, в которой Вы упомянуты
95
+ global_preferences_label: Настройки форума
96
+ messageboard_auto_follow_topics:
97
+ hint: Автоматически следовать все новые темы в этом ОБЪЯВЛЕНИЯ. Это отменяет соответствующую настройку
98
+ выше.
99
+ label: Соблюдайте все новые темы
100
+ messageboard_follow_topics_on_mention:
101
+ hint: 'Когда кто-то упоминает вас на форуме (например: @sam), Вы будете наблюдать за этой темой.'
102
+ label: :thredded.preferences.form.follow_topics_on_mention.label
103
+ messageboard_notifications_for_followed_topics:
104
+ label: :thredded.preferences.form.notifications_for_followed_topics.label
105
+ messageboard_preferences_label_html: Настройки уведомлений для <em>%{messageboard}</em>
106
+ notifications_for_followed_topics:
107
+ label: Уведомления для отслеживаемых тем
108
+ notifications_for_private_topics:
109
+ label: Уведомления для личных сообщений
110
+ submit_btn: Сохранить настройки
111
+ title: Настройки
112
+ update_btn_submitting: :thredded.form.update_btn_submitting
113
+ updated_notice: Ваши настройки были обновлены.
114
+ private_posts:
115
+ form:
116
+ content_label: Сообшение
117
+ create_btn: Послать сообщение
118
+ create_btn_submitting: Посылаю...
119
+ update_btn_submitting: :thredded.form.update_btn_submitting
120
+ private_topics:
121
+ edit: Редактировать
122
+ errors:
123
+ user_ids_length: Выберите хотя-бы одного пользователя.
124
+ form:
125
+ content_label: :thredded.private_posts.form.content_label
126
+ create_btn: :thredded.private_posts.form.create_btn
127
+ create_btn_submitting: :thredded.private_posts.form.create_btn_submitting
128
+ title_label: :thredded.topics.form.title_label
129
+ title_placeholder_new: Необходимо написать предмет переписки
130
+ title_placeholder_start: Начать новую переписку
131
+ update_btn: Обновить
132
+ update_btn_submitting: :thredded.private_posts.form.update_btn_submitting
133
+ users_label: Участники
134
+ users_placeholder: Выберите пользователей для участия в переписке
135
+ no_private_topics:
136
+ create_btn: Начать вашу первую приватную переписку
137
+ title: У вас нет личных сообщений.
138
+ updated_notice: Заголовок обновлен
139
+ recent_activity: Активность
140
+ search:
141
+ form:
142
+ btn_submit: :thredded.search.form.label
143
+ label: Поиск
144
+ placeholder: Поиск тем или записей
145
+ time_ago: "%{time} назад"
146
+ topics:
147
+ delete_confirm: Вы уверены что хотите удалить эту тему? Это безвозвратно.
148
+ delete_topic: Удалить тему
149
+ deleted_notice: Тема "удалена"
150
+ edit: Редактировать тему
151
+ follow: Наблюдать за темой
152
+ followed_by: Наблюдаю
153
+ followed_by_noone: Никто не наблюдает за этой темой
154
+ followed_notice: Вы следите за темой
155
+ following:
156
+ auto: Вы подписаны на эту тему, потому что автоматическое наблюдение включено.
157
+ manual: Вы следите за этой темой.
158
+ mentioned: Вы следите за этой темой, потому что упомянуты в ней.
159
+ posted: Вы следите за темой, потому что Вы писали в ней.
160
+ form:
161
+ categories_placeholder: Категории
162
+ content_label: :thredded.posts.form.content_label
163
+ create_btn: Создать новую тему
164
+ messageboard_label: Форум
165
+ title_label: Заголовок
166
+ title_placeholder: :thredded.topics.form.title_label
167
+ title_placeholder_start: Начать новую тему
168
+ update_btn: Обновление темы
169
+ locked:
170
+ label: Заблокировать тему
171
+ mark_as_unread: Пометить как непрочитанное
172
+ not_following: не отслеживаю
173
+ search:
174
+ no_results_message: Там нет никаких результатов для этой категории - %{query}
175
+ page_title: Темы Результаты поиска
176
+ results_message: Результаты поиска для %{query}
177
+ started_by_html: Начат %{user} %{time_ago}
178
+ sticky:
179
+ label: Закрепить
180
+ unfollow: Не следить за темой
181
+ unfollowed_notice: Вы не следите за темой
182
+ updated_notice: Тема обновлена
183
+ users:
184
+ currently_online: Онлайн
185
+ last_active_html: Последняя активность %{time_ago}
186
+ posted_in_topic_html: Сделан пост в %{topic_link}
187
+ posts_count:
188
+ one: Сделан пост
189
+ other: Сделано постов %{count} раз
190
+ recent_activity: :thredded.recent_activity
191
+ started_topic_html: Начато %{topic_link}
192
+ started_topics_count:
193
+ one: Начата тема
194
+ other: Начато %{count} тем
195
+ user_posted_in_topic_html: "%{user_link} сделал запись в %{topic_link}"
196
+ user_since_html: Пользователь был %{time_ago}
197
+ user_started_topic_html: "%{user_link} начал %{topic_link}"
@@ -45,14 +45,6 @@ class CreateThredded < ActiveRecord::Migration
45
45
  t.index [:slug], name: :index_thredded_messageboards_on_slug
46
46
  end
47
47
 
48
- create_table :thredded_post_notifications do |t|
49
- t.string :email, limit: 191, null: false
50
- t.references :post, null: false
51
- t.timestamps null: false
52
- t.string :post_type, limit: 191
53
- t.index [:post_id, :post_type], name: :index_thredded_post_notifications_on_post
54
- end
55
-
56
48
  create_table :thredded_posts do |t|
57
49
  t.integer :user_id, limit: 4
58
50
  t.text :content, limit: 65_535
@@ -161,6 +153,7 @@ class CreateThredded < ActiveRecord::Migration
161
153
  create_table :thredded_user_preferences do |t|
162
154
  t.references :user, null: false
163
155
  t.boolean :follow_topics_on_mention, default: true, null: false
156
+ t.boolean :auto_follow_topics, default: false, null: false
164
157
  t.timestamps null: false
165
158
  t.index [:user_id], name: :index_thredded_user_preferences_on_user_id
166
159
  end
@@ -169,6 +162,7 @@ class CreateThredded < ActiveRecord::Migration
169
162
  t.references :user, null: false
170
163
  t.references :messageboard, null: false
171
164
  t.boolean :follow_topics_on_mention, default: true, null: false
165
+ t.boolean :auto_follow_topics, default: false, null: false
172
166
  t.timestamps null: false
173
167
  t.index [:user_id, :messageboard_id],
174
168
  name: :thredded_user_messageboard_preferences_user_id_messageboard_id,
@@ -25,16 +25,17 @@ class UpgradeV08ToV09 < ActiveRecord::Migration
25
25
  name: 'thredded_messageboard_notifications_for_followed_topics_unique', unique: true
26
26
  end
27
27
 
28
- Thredded::UserPreference.includes(:user).each do |pref|
28
+ Thredded::UserPreference.all.each do |pref|
29
29
  pref.notifications_for_private_topics.create(notifier_key: 'email', enabled: pref.notify_on_message)
30
30
  pref.notifications_for_followed_topics.create(notifier_key: 'email', enabled: pref.followed_topic_emails)
31
31
  end
32
- Thredded::UserMessageboardPreference.includes(:user).each do |pref|
32
+ Thredded::UserMessageboardPreference.pluck(:user_id, :messageboard_id, :followed_topic_emails)
33
+ .each do |user_id, messageboard_id, emails|
33
34
  Thredded::MessageboardNotificationsForFollowedTopics.create(
34
- user_id: pref.user_id,
35
- messageboard_id: pref.messageboard_id,
35
+ user_id: user_id,
36
+ messageboard_id: messageboard_id,
36
37
  notifier_key: 'email',
37
- enabled: pref.followed_topic_emails
38
+ enabled: emails
38
39
  )
39
40
  end
40
41
 
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ class UpgradeThreddedV010ToV011 < ActiveRecord::Migration
3
+ def up
4
+ drop_table :thredded_post_notifications
5
+ add_column :thredded_user_preferences, :auto_follow_topics, :boolean, default: false, null: false
6
+ add_column :thredded_user_messageboard_preferences, :auto_follow_topics, :boolean, default: false, null: false
7
+ end
8
+
9
+ def down
10
+ remove_column :thredded_user_messageboard_preferences, :auto_follow_topics
11
+ remove_column :thredded_user_preferences, :auto_follow_topics
12
+ create_table :thredded_post_notifications do |t|
13
+ t.string :email, limit: 191, null: false
14
+ t.references :post, null: false
15
+ t.timestamps null: false
16
+ t.string :post_type, limit: 191
17
+ t.index [:post_id, :post_type], name: :index_thredded_post_notifications_on_post
18
+ end
19
+ end
20
+ end
@@ -68,11 +68,23 @@ Thredded.messageboards_order = :position
68
68
 
69
69
  # Emails going out will prefix the "Subject:" with the following string
70
70
  # Thredded.email_outgoing_prefix = '[My Forum] '
71
+ #
72
+ # The parent mailer for all Thredded mailers
73
+ # Thredded.parent_mailer = 'ActionMailer::Base'
71
74
 
72
75
  # ==> View Configuration
73
76
  # Set the layout for rendering the thredded views.
74
77
  Thredded.layout = 'thredded/application'
75
78
 
79
+ # ==> URLs
80
+ # How Thredded generates URL slugs from text.
81
+
82
+ # Default:
83
+ # Thredded.slugifier = ->(input) { input.parameterize }
84
+
85
+ # If your forum is in a language other than English, you might want to use the babosa gem instead
86
+ # Thredded.slugifier = ->(input) { Babosa::Identifier.new(input).normalize.to_s }
87
+
76
88
  # ==> Post Content Formatting
77
89
  # Customize the way Thredded handles post formatting.
78
90
 
@@ -6,8 +6,6 @@ require 'db_text_search'
6
6
  require 'friendly_id'
7
7
  require 'html/pipeline'
8
8
  require 'html/pipeline/sanitization_filter'
9
- require 'html/pipeline/vimeo/vimeo_filter'
10
- require 'html/pipeline/youtube/youtube_filter'
11
9
  require 'rinku'
12
10
  require 'kaminari'
13
11
  require 'rb-gravatar'
@@ -16,9 +14,11 @@ require 'inline_svg'
16
14
 
17
15
  # Require these explictly to make sure they are not reloaded.
18
16
  # This allows for configuring them by accessing class methods in the initializer.
17
+ require 'thredded/formatting_demo_content'
19
18
  require 'thredded/html_pipeline/at_mention_filter'
20
19
  require 'thredded/html_pipeline/autolink_filter'
21
20
  require 'thredded/html_pipeline/kramdown_filter'
21
+ require 'thredded/html_pipeline/onebox_filter'
22
22
  require 'thredded/html_pipeline/wrap_iframes_filter'
23
23
 
24
24
  # Asset compilation
@@ -36,8 +36,9 @@ require 'thredded/errors'
36
36
  require 'thredded/view_hooks/config'
37
37
  require 'thredded/view_hooks/renderer'
38
38
 
39
- # Require Thredded::ContentFormatter explicitly so that it doesn't need to be required if used in the initializer.
39
+ # Require these explicitly so that they do not need to be required if used in the initializer:
40
40
  require 'thredded/content_formatter'
41
+ require 'thredded/email_transformer'
41
42
 
42
43
  require 'thredded/collection_to_strings_with_cache_renderer'
43
44
 
@@ -77,6 +78,14 @@ module Thredded
77
78
  # @return [Symbol] The name of the method used by Thredded to display users
78
79
  mattr_accessor :user_display_name_method
79
80
 
81
+ # @return [String] The name of the parent mailer class for Thredded mailers.
82
+ mattr_accessor :parent_mailer
83
+ self.parent_mailer = 'ActionMailer::Base'
84
+
85
+ # @return [Proc] The proc that Thredded uses to generate URL slugs from text.
86
+ mattr_accessor :slugifier
87
+ self.slugifier = ->(input) { input.parameterize }
88
+
80
89
  # @return [Boolean] Whether the user should get subscribed to a new topic they've created.
81
90
  mattr_accessor :auto_follow_when_creating_topic
82
91
  self.auto_follow_when_creating_topic = true
@@ -9,34 +9,19 @@ module Thredded
9
9
  elements: HTML::Pipeline::SanitizationFilter::WHITELIST[:elements] + %w(iframe span figure figcaption),
10
10
  transformers: HTML::Pipeline::SanitizationFilter::WHITELIST[:transformers] + [
11
11
  lambda do |env|
12
- node = env[:node]
13
-
14
- a_tags = node.css('a')
15
- a_tags.each do |a_tag|
16
- a_tag['href'] ||= '#'
17
- if a_tag['href'].starts_with? 'http'
18
- a_tag['target'] = '_blank'
19
- a_tag['rel'] = 'nofollow noopener'
20
- end
12
+ next unless env[:node_name] == 'a'
13
+ a_tag = env[:node]
14
+ a_tag['href'] ||= '#'
15
+ if a_tag['href'] =~ %r{^(?:[a-z]+:)?//}
16
+ a_tag['target'] = '_blank'
17
+ a_tag['rel'] = 'nofollow noopener'
21
18
  end
22
19
  end
23
20
  ],
24
- attributes: {
21
+ attributes: {
25
22
  'a' => %w(href rel),
26
- 'iframe' => %w(src width height frameborder allowfullscreen sandbox seamless),
27
23
  'span' => %w(class),
28
24
  'div' => %w(class)
29
- },
30
- add_attributes: {
31
- 'iframe' => {
32
- 'seamless' => 'seamless',
33
- 'sandbox' => 'allow-same-origin allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox',
34
- }
35
- },
36
- protocols: {
37
- 'iframe' => {
38
- 'src' => ['https', 'http', :relative]
39
- }
40
25
  }
41
26
  )
42
27
 
@@ -44,8 +29,6 @@ module Thredded
44
29
  # input: markup, output: markup.
45
30
  mattr_accessor :before_markup_filters
46
31
  self.before_markup_filters = [
47
- HTML::Pipeline::VimeoFilter,
48
- HTML::Pipeline::YoutubeFilter,
49
32
  ]
50
33
 
51
34
  # Markup filters, such as BBCode, Markdown, Autolink, etc.
@@ -64,7 +47,6 @@ module Thredded
64
47
  Thredded::HtmlPipeline::AutolinkFilter,
65
48
  HTML::Pipeline::EmojiFilter,
66
49
  Thredded::HtmlPipeline::AtMentionFilter,
67
- Thredded::HtmlPipeline::WrapIframesFilter,
68
50
  ]
69
51
 
70
52
  # Filters that sanitize the resulting HTML.
@@ -74,6 +56,14 @@ module Thredded
74
56
  HTML::Pipeline::SanitizationFilter,
75
57
  ]
76
58
 
59
+ # Filters that run after sanitization
60
+ # input: sanitized html, output: html
61
+ mattr_accessor :after_sanitization_filters
62
+ self.after_sanitization_filters = [
63
+ Thredded::HtmlPipeline::OneboxFilter,
64
+ Thredded::HtmlPipeline::WrapIframesFilter,
65
+ ]
66
+
77
67
  # All the HTML::Pipeline filters, read-only.
78
68
  def self.pipeline_filters
79
69
  filters = [
@@ -81,6 +71,7 @@ module Thredded
81
71
  *markup_filters,
82
72
  *after_markup_filters,
83
73
  *sanitization_filters,
74
+ *after_sanitization_filters
84
75
  ]
85
76
  # Changing the result in-place has no effect on the ContentFormatter output,
86
77
  # and is most likely the result of a programmer error.
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+ require 'thredded/email_transformer/onebox'
3
+
4
+ module Thredded
5
+ # This transformer should applied to emails so that they render correctly in the email clients.
6
+ #
7
+ # For example, if you use roadie, you can configure it to use the transformer in the initializer:
8
+ #
9
+ # # config/initializers/roadie.rb
10
+ # Rails.application.config.roadie.before_transformation = Thredded::EmailTransformer
11
+ #
12
+ module EmailTransformer
13
+ mattr_accessor :transformers
14
+ self.transformers = [Onebox]
15
+
16
+ # @param doc [Nokogiri::HTML::Document]
17
+ def self.call(doc)
18
+ transformers.each { |transformer| transformer.call(doc) }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Thredded
4
+ module EmailTransformer
5
+ # A helper module with common functions for constructing Nokogiri elements.
6
+ module Helpers
7
+ # Creates a `<p>` node with the given child
8
+ def paragraph(child)
9
+ Nokogiri::XML::Node.new('p', doc).tap do |p|
10
+ p.add_child child
11
+ end
12
+ end
13
+
14
+ # Creates an `<a>` node with the given attributes and content
15
+ def anchor(href, target: '_blank', content: href)
16
+ Nokogiri::XML::Node.new('a', doc).tap do |a|
17
+ a['href'] = href
18
+ a['target'] = target
19
+ a.content = content
20
+ end
21
+ end
22
+ end
23
+
24
+ class Base
25
+ include Helpers
26
+
27
+ # @return [Nokogiri::HTML::Document]
28
+ attr_reader :doc
29
+
30
+ # @param doc [Nokogiri::HTML::Document]
31
+ def initialize(doc)
32
+ @doc = doc
33
+ end
34
+
35
+ def self.inherited(base)
36
+ base.extend ClassMethods
37
+ end
38
+
39
+ module ClassMethods
40
+ # @param doc [Nokogiri::HTML::Document]
41
+ def call(doc)
42
+ new(doc).call
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end