thredded 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c38b0b431b19a2a3bcb74955be64a67835d60870754e65436e8498ca67729bc8
4
- data.tar.gz: 1b9827d5ed79af58f52c86e5badb430e1b44dfaff0381fde2390ad08ce436b26
3
+ metadata.gz: 19cde941264a9f9b9427694c27cc5f2a668fd18debbfe459d3fc58087e5636bf
4
+ data.tar.gz: 0d4eec1e395f2265783f9283ad958ec2a7f486a017bb961af87b26c2fd711c20
5
5
  SHA512:
6
- metadata.gz: 43a2362878a9949d88097d77efe90c7997483e1c70f0fb505ffff1fa06e2097036d6ae6aff829120a406bac06b9e1cbb0879c1b614cf0c8205f837044a6fb105
7
- data.tar.gz: 6f59d7de62c088da6ef53bb474ab02bdc666313ff5e050f86c3a1414a7371d93d60874008dc2ce68b8df8a7601754fe9771fef1804e11e1a4060620968465917
6
+ metadata.gz: f7d6aa4fd6d1eaecda06e839b757d6fa2bbf7fd24ae6ef4ba3c238a5d8880baeff1be6b9ee2aae21b34c8f844d0aa5eb5c41a1f70e7841cbe867a900e29b980a
7
+ data.tar.gz: 04af99833299683e35b13468e957bd75880a1627db1ff6c9ab53e1678f99842b273cc50ed529c9cddeedb7600c0d54b404550fd8858a7901346d6c72df77bdb2
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Thredded [![Code Climate](https://codeclimate.com/github/thredded/thredded/badges/gpa.svg)](https://codeclimate.com/github/thredded/thredded) [![Travis-CI](https://api.travis-ci.org/thredded/thredded.svg?branch=main)](https://travis-ci.org/thredded/thredded/) [![Test Coverage](https://codeclimate.com/github/thredded/thredded/badges/coverage.svg)](https://codeclimate.com/github/thredded/thredded/coverage) [![Inline docs](http://inch-ci.org/github/thredded/thredded.svg?branch=main)](http://inch-ci.org/github/thredded/thredded) [![Gitter](https://badges.gitter.im/thredded/thredded.svg)](https://gitter.im/thredded/thredded?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
2
2
 
3
- _Thredded_ is a Rails 5.2+ forum/messageboard engine. Its goal is to be as simple and feature rich as possible.
3
+ _Thredded_ is a Rails 6.0+ forum/messageboard engine. Its goal is to be as simple and feature rich as possible.
4
4
 
5
5
  Some of the features currently in Thredded:
6
6
 
@@ -38,6 +38,7 @@ Table of Contents
38
38
  * [Adding Thredded to an existing Rails app](#adding-thredded-to-an-existing-rails-app)
39
39
  * [Upgrading an existing install](#upgrading-an-existing-install)
40
40
  * [Migrating from Forem](#migrating-from-forem)
41
+ * [Rails compatibility](#rails-compatibility)
41
42
  * [Views and other assets](#views-and-other-assets)
42
43
  * [Standalone layout](#standalone-layout)
43
44
  * [Application layout](#application-layout)
@@ -96,7 +97,7 @@ Then, see the rest of this Readme for more information about using and customizi
96
97
  Add the gem to your Gemfile:
97
98
 
98
99
  ```ruby
99
- gem 'thredded', '~> 1.0'
100
+ gem 'thredded', '~> 1.1'
100
101
  ```
101
102
 
102
103
  Add the Thredded [initializer] to your parent app by running the install generator.
@@ -155,6 +156,15 @@ to Thredded.
155
156
  [forem-to-thredded]: https://github.com/thredded/thredded/wiki/Migrate-from-Forem
156
157
  [Forem]: https://github.com/rubysherpas/forem
157
158
 
159
+ ## Rails compatibility
160
+
161
+ | Rails | Latest Thredded |
162
+ | ------------- |------------------|
163
+ | Rails 6.0+ | Thredded 1.1+ |
164
+ | Rails 5.2 | Thredded 1.0.1 |
165
+ | Rails 4.2 | Thredded 0.16.16 |
166
+
167
+
158
168
  ## Views and other assets
159
169
 
160
170
  ### Standalone layout
@@ -596,8 +606,6 @@ Rails.application.config.to_prepare do
596
606
  Thredded::ApplicationController.module_eval do
597
607
  # Require authentication to access the forums:
598
608
  before_action :thredded_require_login!
599
- # NB: in rails 4.2 you will need to change this to:
600
- # before_action { thredded_require_login! }
601
609
 
602
610
  # You may also want to render a login form after the
603
611
  # "Please sign in first" message:
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Thredded
4
4
  module UrlsHelper # rubocop:disable Metrics/ModuleLength
5
+ include Thredded::Engine.routes.url_helpers
6
+
5
7
  class << self
6
8
  include Thredded::Engine.routes.url_helpers
7
9
  include Thredded::UrlsHelper
@@ -9,6 +9,7 @@ module Thredded
9
9
  :empty?,
10
10
  :[],
11
11
  :each,
12
+ :each_with_index,
12
13
  :map,
13
14
  :size,
14
15
  to: :@topic_views
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # exit on first failure
4
+ set -e
5
+ for i in {1..10}
6
+ do
7
+ echo "#$i (rspec $1)"
8
+ bundle exec rspec --format d $1 --fail-fast
9
+ done
@@ -47,7 +47,8 @@ module Thredded
47
47
 
48
48
  ordered_keys.map do |cache_key|
49
49
  [keyed_collection[cache_key], cached_partials[cache_key] || rendered_partials.next.tap do |rendered|
50
- cached_partials[cache_key] = cache.write(cache_key, rendered, expires_in: expires_in)
50
+ cache.write(cache_key, rendered, expires_in: expires_in)
51
+ cached_partials[cache_key] = rendered
51
52
  end]
52
53
  end
53
54
  end
@@ -82,18 +83,29 @@ module Thredded
82
83
  else
83
84
  collection.each_slice(collection.size / num_threads).map do |slice|
84
85
  Thread.start do
85
- # `ActionView::PartialRenderer` mutates the contents of `opts[:locals]`, `opts[:locals][:as]` in particular:
86
- # https://github.com/rails/rails/blob/v6.0.2.1/actionview/lib/action_view/renderer/partial_renderer.rb#L379
87
- # https://github.com/rails/rails/blob/v6.0.2.1/actionview/lib/action_view/renderer/partial_renderer.rb#L348-L356
88
- opts[:locals] = opts[:locals].dup if opts[:locals]
89
86
  ActiveRecord::Base.connection_pool.with_connection do
90
- render_partials_serial(view_context.dup, slice, opts)
87
+ render_partials_serial(view_context.dup, slice, dup_opts(opts))
91
88
  end
92
89
  end
93
90
  end.flat_map(&:value)
94
91
  end
95
92
  end
96
93
 
94
+ # `ActionView::PartialRenderer` mutates the contents of `opts[:locals]`, `opts[:locals][:as]` in particular:
95
+ # https://github.com/rails/rails/blob/v6.0.2.1/actionview/lib/action_view/renderer/partial_renderer.rb#L379
96
+ # https://github.com/rails/rails/blob/v6.0.2.1/actionview/lib/action_view/renderer/partial_renderer.rb#L348-L356
97
+ def dup_opts(opts)
98
+ if opts[:locals]
99
+ opts = opts.dup
100
+ # sometimes have a thread safe :users_provider, preserve that for performance reasons
101
+ # hence not doing a deep_dup
102
+ opts[:locals] = opts[:locals].dup
103
+ opts
104
+ else
105
+ opts.dup
106
+ end
107
+ end
108
+
97
109
  if Thredded::Compat.rails_gte_61?
98
110
  # @param [Array<Object>] collection
99
111
  # @param [Hash] opts
@@ -121,42 +133,20 @@ module Thredded
121
133
  view.combined_fragment_cache_key(key)
122
134
  end
123
135
 
124
- if Thredded::Compat.rails_gte_60?
125
- def cache_fragment_name(view, key, virtual_path:, digest_path:)
126
- if Thredded::Compat.rails_gte_61?
127
- view.cache_fragment_name(key, digest_path: digest_path)
128
- else
129
- view.cache_fragment_name(key, virtual_path: virtual_path, digest_path: digest_path)
130
- end
131
- end
132
-
133
- def digest_path_from_template(view, template)
134
- view.digest_path_from_template(template)
135
- end
136
-
137
- def render_partial(partial_renderer, view_context, opts)
138
- partial_renderer.render(view_context, opts, nil).body
139
- end
140
- else
141
- def cache_fragment_name(_view, key, virtual_path:, digest_path:)
142
- if digest_path
143
- ["#{virtual_path}:#{digest_path}", key]
144
- else
145
- [virtual_path, key]
146
- end
136
+ def cache_fragment_name(view, key, virtual_path:, digest_path:)
137
+ if Thredded::Compat.rails_gte_61?
138
+ view.cache_fragment_name(key, digest_path: digest_path)
139
+ else
140
+ view.cache_fragment_name(key, virtual_path: virtual_path, digest_path: digest_path)
147
141
  end
142
+ end
148
143
 
149
- def digest_path_from_template(view, template)
150
- ActionView::Digestor.digest(
151
- name: template.virtual_path,
152
- finder: @lookup_context,
153
- dependencies: view.view_cache_dependencies
154
- ).presence
155
- end
144
+ def digest_path_from_template(view, template)
145
+ view.digest_path_from_template(template)
146
+ end
156
147
 
157
- def render_partial(partial_renderer, view_context, opts)
158
- partial_renderer.render(view_context, opts, nil)
159
- end
148
+ def render_partial(partial_renderer, view_context, opts)
149
+ partial_renderer.render(view_context, opts, nil).body
160
150
  end
161
151
  end
162
152
  end
@@ -3,12 +3,6 @@
3
3
  module Thredded
4
4
  module Compat
5
5
  class << self
6
- # @api private
7
- def rails_gte_60?
8
- @rails_gte_60 = (Rails.gem_version >= Gem::Version.new('6.0.0')) if @rails_gte_60.nil?
9
- @rails_gte_60
10
- end
11
-
12
6
  # @api private
13
7
  def rails_gte_61?
14
8
  @rails_gte_61 = (Rails.gem_version >= Gem::Version.new('6.1.0')) if @rails_gte_61.nil?
@@ -8,7 +8,15 @@ module Thredded
8
8
  attr_accessor :allowlist
9
9
 
10
10
  # TODO: v2.0: drop alias and just use allowlist
11
- alias_attribute :whitelist, :allowlist
11
+ # @deprecated use allowlist
12
+ def whitelist
13
+ ActiveSupport::Deprecation.warn(<<~MESSAGE.squish)
14
+ ContentFormatter.whitelist is deprecated and will be removed in Thredded 2.0.
15
+ Use ContentFormatter.allowlist instead
16
+ MESSAGE
17
+
18
+ allowlist
19
+ end
12
20
 
13
21
  # Filters that run before processing the markup.
14
22
  # input: markup, output: markup.
@@ -30,17 +38,8 @@ module Thredded
30
38
  # input: sanitized html, output: html
31
39
  attr_accessor :after_sanitization_filters
32
40
 
33
- # TODO: v1.1: only allow html-pipeline >= 2.14.1 and drop this
34
- def sanitization_filter_uses_allowlist?
35
- defined?(HTML::Pipeline::SanitizationFilter::ALLOWLIST)
36
- end
37
-
38
41
  def sanitization_filter_allowlist_config
39
- if sanitization_filter_uses_allowlist?
40
- HTML::Pipeline::SanitizationFilter::ALLOWLIST
41
- else
42
- HTML::Pipeline::SanitizationFilter::WHITELIST
43
- end
42
+ HTML::Pipeline::SanitizationFilter::ALLOWLIST
44
43
  end
45
44
  end
46
45
 
@@ -150,15 +149,9 @@ module Thredded
150
149
 
151
150
  # @return [Hash] options for HTML::Pipeline.new
152
151
  def content_pipeline_options
153
- option = if self.class.sanitization_filter_uses_allowlist?
154
- :allowlist
155
- else
156
- # TODO: v1.1: only allow html-pipeline >= 2.14.1 and drop this
157
- :whitelist
158
- end
159
152
  {
160
153
  asset_root: Rails.application.config.action_controller.asset_host || '',
161
- option => ContentFormatter.allowlist
154
+ allowlist: ContentFormatter.allowlist
162
155
  }
163
156
  end
164
157
  end
@@ -10,11 +10,7 @@ module Thredded
10
10
  verbose_was = ActiveRecord::Migration.verbose
11
11
  ActiveRecord::Migration.verbose = !quiet
12
12
  migrate =
13
- if Thredded::Compat.rails_gte_60?
14
- -> { ActiveRecord::MigrationContext.new(paths, ActiveRecord::SchemaMigration).migrate(nil, &filter) }
15
- else # Rails 5.2
16
- -> { ActiveRecord::MigrationContext.new(paths).migrate(nil, &filter) }
17
- end
13
+ -> { ActiveRecord::MigrationContext.new(paths, ActiveRecord::SchemaMigration).migrate(nil, &filter) }
18
14
  if quiet
19
15
  silence_active_record(&migrate)
20
16
  else
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Thredded
4
- VERSION = '1.0.1'
4
+ VERSION = '1.1.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thredded
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Oliveira
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-06-05 00:00:00.000000000 Z
12
+ date: 2023-02-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: active_record_union
@@ -127,20 +127,14 @@ dependencies:
127
127
  name: rails
128
128
  requirement: !ruby/object:Gem::Requirement
129
129
  requirements:
130
- - - ">="
131
- - !ruby/object:Gem::Version
132
- version: 5.2.0
133
- - - "!="
130
+ - - ">"
134
131
  - !ruby/object:Gem::Version
135
132
  version: 6.0.0.rc2
136
133
  type: :runtime
137
134
  prerelease: false
138
135
  version_requirements: !ruby/object:Gem::Requirement
139
136
  requirements:
140
- - - ">="
141
- - !ruby/object:Gem::Version
142
- version: 5.2.0
143
- - - "!="
137
+ - - ">"
144
138
  - !ruby/object:Gem::Version
145
139
  version: 6.0.0.rc2
146
140
  - !ruby/object:Gem::Dependency
@@ -163,14 +157,14 @@ dependencies:
163
157
  requirements:
164
158
  - - ">="
165
159
  - !ruby/object:Gem::Version
166
- version: '0'
160
+ version: 2.14.1
167
161
  type: :runtime
168
162
  prerelease: false
169
163
  version_requirements: !ruby/object:Gem::Requirement
170
164
  requirements:
171
165
  - - ">="
172
166
  - !ruby/object:Gem::Version
173
- version: '0'
167
+ version: 2.14.1
174
168
  - !ruby/object:Gem::Dependency
175
169
  name: kramdown
176
170
  requirement: !ruby/object:Gem::Requirement
@@ -634,7 +628,7 @@ dependencies:
634
628
  - !ruby/object:Gem::Version
635
629
  version: '0'
636
630
  description: |-
637
- The best Rails 5.2+ forums engine ever. Its goal is to be as simple and feature rich as possible.
631
+ The best Rails 6.0+ forums engine ever. Its goal is to be as simple and feature rich as possible.
638
632
  Thredded works with SQLite, MySQL (v5.6.4+), and PostgreSQL. See the demo at https://thredded.org/.
639
633
  email:
640
634
  - joel@thredded.com
@@ -985,6 +979,7 @@ files:
985
979
  - bin/create_migration_fixture
986
980
  - bin/rails
987
981
  - bin/rubocop
982
+ - bin/run_specs_repeatedly
988
983
  - config/i18n-tasks.yml
989
984
  - config/locales/de.yml
990
985
  - config/locales/en.yml
@@ -1034,7 +1029,6 @@ files:
1034
1029
  - lib/thredded/html_pipeline/spoiler_tag_filter.rb
1035
1030
  - lib/thredded/html_pipeline/utils.rb
1036
1031
  - lib/thredded/html_pipeline/wrap_iframes_filter.rb
1037
- - lib/thredded/rails_lt_5_2_arel_case_node.rb
1038
1032
  - lib/thredded/users_provider.rb
1039
1033
  - lib/thredded/version.rb
1040
1034
  - lib/thredded/view_hooks/config.rb
@@ -1,119 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Arel
4
- module Nodes
5
- class Case < Arel::Nodes::Node
6
- include Arel::OrderPredications
7
- include Arel::Predications
8
- include Arel::AliasPredication
9
-
10
- attr_accessor :case, :conditions, :default
11
-
12
- def initialize(expression = nil, default = nil)
13
- @case = expression
14
- @conditions = []
15
- @default = default
16
- end
17
-
18
- def when(condition, expression = nil)
19
- @conditions << When.new(Nodes.build_quoted(condition), expression)
20
- self
21
- end
22
-
23
- def then(expression)
24
- @conditions.last.right = Nodes.build_quoted(expression)
25
- self
26
- end
27
-
28
- def else(expression)
29
- @default = Else.new Nodes.build_quoted(expression)
30
- self
31
- end
32
-
33
- def initialize_copy(other)
34
- super
35
- @case = @case.clone if @case
36
- @conditions = @conditions.map(&:clone)
37
- @default = @default.clone if @default
38
- end
39
-
40
- def hash
41
- [@case, @conditions, @default].hash
42
- end
43
-
44
- def eql?(other)
45
- self.class == other.class &&
46
- self.case == other.case &&
47
- conditions == other.conditions &&
48
- default == other.default
49
- end
50
-
51
- alias == eql?
52
- end
53
-
54
- class When < Binary
55
- end
56
-
57
- class Else < Unary
58
- end
59
- end
60
- end
61
-
62
- module Arel
63
- module Visitors
64
- class DepthFirst < Arel::Visitors::Visitor
65
- alias visit_Arel_Nodes_Else unary
66
-
67
- def visit_Arel_Nodes_Case(o) # rubocop:disable Naming/MethodName
68
- visit o.case
69
- visit o.conditions
70
- visit o.default
71
- end
72
-
73
- alias visit_Arel_Nodes_When binary
74
- end
75
- end
76
- end
77
-
78
- module Arel
79
- module Predications
80
- def when(right)
81
- Nodes::Case.new(self).when quoted_node(right)
82
- end
83
- end
84
- end
85
-
86
- module Arel
87
- module Visitors
88
- class ToSql < Arel::Visitors::Reduce
89
- def visit_Arel_Nodes_Case(o, collector) # rubocop:disable Naming/MethodName
90
- collector << 'CASE '
91
- if o.case
92
- visit o.case, collector
93
- collector << ' '
94
- end
95
- o.conditions.each do |condition|
96
- visit condition, collector
97
- collector << ' '
98
- end
99
- if o.default
100
- visit o.default, collector
101
- collector << ' '
102
- end
103
- collector << 'END'
104
- end
105
-
106
- def visit_Arel_Nodes_When(o, collector) # rubocop:disable Naming/MethodName
107
- collector << 'WHEN '
108
- visit o.left, collector
109
- collector << ' THEN '
110
- visit o.right, collector
111
- end
112
-
113
- def visit_Arel_Nodes_Else(o, collector) # rubocop:disable Naming/MethodName
114
- collector << 'ELSE '
115
- visit o.expr, collector
116
- end
117
- end
118
- end
119
- end