thredded 1.0.1 → 1.1.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: 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