card 1.99.5 → 1.99.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/db/migrate_core_cards/20140629222005_add_email_cards.rb +1 -1
  4. data/lib/card.rb +13 -23
  5. data/lib/card/act_manager.rb +1 -0
  6. data/lib/card/act_manager/event_delay.rb +10 -5
  7. data/lib/card/act_manager/subdirector_array.rb +2 -0
  8. data/lib/card/auth/current.rb +0 -2
  9. data/lib/card/cache/prepopulate.rb +4 -4
  10. data/lib/card/env.rb +9 -53
  11. data/lib/card/env/location.rb +15 -2
  12. data/lib/card/env/request_assignments.rb +24 -0
  13. data/lib/card/env/serialization.rb +24 -0
  14. data/lib/card/env/slot_options.rb +30 -0
  15. data/lib/card/format/error.rb +6 -1
  16. data/lib/card/mod/loader/set_pattern_loader.rb +5 -1
  17. data/lib/card/model/save_helper.rb +5 -1
  18. data/lib/card/set/event/delayed_event.rb +49 -9
  19. data/lib/card/set/event/options.rb +1 -0
  20. data/lib/card/set/pattern/base.rb +18 -0
  21. data/lib/card/subcards.rb +11 -8
  22. data/lib/card/subcards/add.rb +7 -4
  23. data/lib/card/view/cache/cache_action.rb +1 -1
  24. data/lib/card/view/classy.rb +9 -9
  25. data/lib/card/view/options/voo_api.rb +0 -8
  26. data/mod/account/set/all/account.rb +2 -2
  27. data/mod/account/spec/set/right/account_spec.rb +2 -2
  28. data/mod/account/spec/set/type/signup_spec.rb +1 -1
  29. data/mod/basic_formats/set/all/head.rb +4 -2
  30. data/mod/basic_formats/set/all/rss.rb +1 -1
  31. data/mod/bootstrap/lib/card/lazy_tab.rb +37 -0
  32. data/mod/bootstrap/lib/card/tab.rb +76 -0
  33. data/mod/bootstrap/set/all/bootstrap/dropdown.rb +0 -1
  34. data/mod/bootstrap/set/all/bootstrap/tabs.rb +33 -124
  35. data/mod/bootstrap/set/all/bootstrap/tabs/tab_panel.haml +7 -0
  36. data/mod/carrierwave/set/abstract/attachment.rb +1 -1
  37. data/mod/carrierwave/set/abstract/attachment/upload_cache.rb +1 -1
  38. data/mod/core/lib/card/rule.rb +227 -0
  39. data/mod/core/set/all/actify.rb +16 -2
  40. data/mod/core/set/all/assign_attributes.rb +2 -2
  41. data/mod/core/set/all/cache.rb +4 -0
  42. data/mod/core/set/all/event_conditions.rb +58 -39
  43. data/mod/core/set/all/fetch.rb +1 -1
  44. data/mod/core/set/all/fetch_helper.rb +5 -13
  45. data/mod/core/set/all/initialize.rb +6 -6
  46. data/mod/core/set/all/name_events.rb +2 -3
  47. data/mod/core/set/all/rename.rb +9 -5
  48. data/mod/core/set/all/rules.rb +3 -228
  49. data/mod/core/set/all/tabs.rb +4 -3
  50. data/mod/core/set/all/update_read_rules.rb +1 -1
  51. data/mod/core/set_pattern/08_type_plus_right.rb +1 -2
  52. data/mod/core/spec/set/all/event_conditions_spec.rb +3 -3
  53. data/mod/core/spec/set/all/fetch_helper_spec.rb +6 -0
  54. data/mod/core/spec/set/all/references_spec.rb +9 -0
  55. data/mod/core/spec/set/all/rules_spec.rb +1 -1
  56. data/mod/developer/set/right/debug.rb +13 -14
  57. data/mod/edit/set/all/bridge.rb +7 -7
  58. data/mod/edit/set/all/bridge/tab_visibility.rb +2 -2
  59. data/mod/follow/set/all/follow/followed_by.rb +1 -2
  60. data/mod/follow/set/all/follow/follower_ids.rb +15 -3
  61. data/mod/follow/set/all/notify.rb +1 -5
  62. data/mod/follow/set/type_plus_right/user/follow.rb +4 -7
  63. data/mod/google_analytics/set/all/google_analytics.rb +1 -1
  64. data/mod/history/lib/card/act.rb +1 -1
  65. data/mod/history/set/all/history.rb +23 -17
  66. data/mod/history/set/all/history/acts.rb +0 -4
  67. data/mod/machines/file/all_script_machine_output/file.js +69 -38418
  68. data/mod/machines/file/all_style_machine_output/file.css +1 -1
  69. data/mod/machines/file/script_html5shiv_printshiv_machine_output/file.js +1 -1
  70. data/mod/machines/lib/javascript/decko/filter_items.js.coffee +4 -4
  71. data/mod/machines/lib/javascript/decko/nest_editor_name.js.coffee +1 -1
  72. data/mod/machines/lib/javascript/decko/selectable_filtered_content.js.coffee +12 -0
  73. data/mod/machines/lib/javascript/decko/slotter.js.coffee +1 -1
  74. data/mod/machines/lib/stylesheets/style_cards.scss +1 -1
  75. data/mod/machines/set/abstract/machine/output_update.rb +12 -4
  76. data/mod/machines/set/self/script_decko.rb +1 -1
  77. data/mod/pointer/set/abstract/00_paging_params.rb +1 -3
  78. data/mod/pointer/set/abstract/02_pointer/events.rb +1 -0
  79. data/mod/recaptcha/set/all/recaptcha.rb +1 -1
  80. data/mod/recaptcha/set/self/admin_info.rb +2 -3
  81. data/mod/rules/set/type/set.rb +1 -1
  82. data/mod/search/set/abstract/00_filter_helper.rb +2 -4
  83. data/mod/search/set/abstract/02_search_params.rb +1 -1
  84. data/mod/search/set/abstract/03_filter.rb +2 -0
  85. data/mod/search/set/abstract/03_filter/selectable_filtered_content.haml +2 -0
  86. data/mod/search/template/abstract/search/checkbox_item.haml +2 -3
  87. data/mod/settings/set/right/read.rb +1 -1
  88. data/mod/standard/set/all/rich_html/error.rb +1 -1
  89. data/mod/standard/set/all/rich_html/menu.rb +1 -1
  90. data/mod/standard/set/all/rich_html/show.rb +8 -0
  91. data/mod/tinymce_editor/set/all/reference_editor/nest_editor.rb +6 -8
  92. metadata +13 -5
  93. data/lib/card/tasks/card/seed.rake +0 -0
@@ -123,7 +123,7 @@ end
123
123
 
124
124
  def renew mark, new_opts
125
125
  return self if new_opts.blank?
126
- opts = new_opts.clone.merge name: mark
126
+ opts = new_opts.clone.reverse_merge name: mark
127
127
  copy = dup
128
128
  handle_default_content opts
129
129
  copy.newish opts
@@ -13,16 +13,6 @@ module ClassMethods
13
13
  end
14
14
  end
15
15
 
16
- def safe_param param
17
- if param.respond_to? :to_unsafe_h
18
- # clone doesn't work for Parameters
19
- param.to_unsafe_h
20
- else
21
- # clone so that original params remain unaltered. need deeper clone?
22
- (param || {}).clone
23
- end
24
- end
25
-
26
16
  private
27
17
 
28
18
  def standard_controller_fetch args, card_opts
@@ -36,10 +26,10 @@ module ClassMethods
36
26
  end
37
27
 
38
28
  def controller_fetch_opts args
39
- opts = safe_param args[:card]
29
+ opts = Env.hash args[:card]
40
30
  opts[:type] ||= args[:type] if args[:type]
41
31
  # for /new/:type shortcut. we should handle in routing and deprecate this
42
- opts[:name] ||= Card::Name.url_key_to_standard(args[:mark])
32
+ opts[:name] ||= Card::Name.url_key_to_standard args[:mark]
43
33
  opts
44
34
  end
45
35
 
@@ -123,8 +113,10 @@ module ClassMethods
123
113
  card = card.renew mark, new_opts
124
114
  elsif opts[:skip_virtual]
125
115
  return nil
116
+ else
117
+ card.assign_name_from_fetched_mark! mark, opts
126
118
  end
127
- card.assign_name_from_fetched_mark! mark, opts
119
+ #
128
120
  finalize_fetch_results card, opts
129
121
  # must include_set_modules before checking `card.known?`,
130
122
  # in case, eg, set modules override #virtual?
@@ -61,12 +61,12 @@ def initial_name name
61
61
  end
62
62
 
63
63
  def include_set_modules
64
- unless @set_mods_loaded
65
- set_modules.each do |m|
66
- singleton_class.send :include, m
67
- end
68
- assign_set_specific_attributes
69
- @set_mods_loaded = true
64
+ return self if @set_mods_loaded
65
+
66
+ set_modules.each do |m|
67
+ singleton_class.send :include, m
70
68
  end
69
+ assign_set_specific_attributes
70
+ @set_mods_loaded = true
71
71
  self
72
72
  end
@@ -18,7 +18,7 @@ event :validate_name, :validate, on: :save, changed: :name do
18
18
  validate_uniqueness_of_name
19
19
  end
20
20
 
21
- event :validate_uniqueness_of_name do
21
+ event :validate_uniqueness_of_name, skip: :allowed do
22
22
  # validate uniqueness of name
23
23
  rel = Card.where key: name.key, trash: false
24
24
  rel = rel.where "id <> ?", id if id
@@ -55,8 +55,7 @@ event :expire_old_name, :store, changed: :name, on: :update do
55
55
  ActManager.expirees << name_before_act
56
56
  end
57
57
 
58
- event :set_left_and_right, :store,
59
- changed: :name, on: :save do
58
+ event :set_left_and_right, :store, changed: :name, on: :save do
60
59
  if name.junction?
61
60
  %i[left right].each do |side|
62
61
  assign_side_id side
@@ -23,18 +23,22 @@ end
23
23
  event :cascade_name_changes, :finalize, on: :update, changed: :name,
24
24
  before: :name_change_finalized do
25
25
  @descendants = nil # reset
26
+ skip_rename_events! if act_card?
26
27
 
27
28
  children.each do |child|
28
29
  Rails.logger.debug "cascading name: #{child.name}"
29
30
  newname = child.name.swap name_before_last_save, name
30
- # not sure if this is still needed since we attach the children as subcards
31
- # (it used to be resolved right here without adding subcards)
32
- ActManager.expirees << child.name
33
- child.skip_event! :check_permissions
34
-
35
31
  # superleft has to be the first argument. Otherwise the call of `name=` in
36
32
  # `assign_attributes` can cause problems because `left` doesn't find the new left.
37
33
  attach_subcard child.name, superleft: self, name: newname,
38
34
  update_referers: update_referers
39
35
  end
40
36
  end
37
+
38
+ private
39
+
40
+ def skip_rename_events!
41
+ # these are skipped for children, because they've already been called in the act card
42
+ skip_event! :validate_uniqueness_of_name, :validate_renaming, :check_permissions
43
+ skip_event! :set_read_rule if name.simple?
44
+ end
@@ -1,60 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
- RULE_SQL = %(
4
- SELECT
5
- rules.id AS rule_id,
6
- settings.id AS setting_id,
7
- sets.id AS set_id,
8
- sets.left_id AS anchor_id,
9
- sets.right_id AS set_tag_id
10
- FROM cards rules
11
- JOIN cards sets ON rules.left_id = sets.id
12
- JOIN cards settings ON rules.right_id = settings.id
13
- WHERE sets.type_id = #{SetID}
14
- AND settings.type_id = #{SettingID}
15
- AND (settings.codename != 'follow' OR rules.db_content != '')
16
- AND rules.trash is false
17
- AND sets.trash is false
18
- AND settings.trash is false;
19
- )
20
-
21
- # FIXME: "follow" hardcoded above
22
-
23
- READ_RULE_SQL = %(
24
- SELECT
25
- refs.referee_id AS party_id,
26
- read_rules.id AS read_rule_id
27
- FROM cards read_rules
28
- JOIN card_references refs ON refs.referer_id = read_rules.id
29
- JOIN cards sets ON read_rules.left_id = sets.id
30
- WHERE read_rules.right_id = #{ReadID}
31
- AND sets.type_id = #{SetID}
32
- AND read_rules.trash is false
33
- AND sets.trash is false;
34
- )
35
-
36
- PREFERENCE_SQL = %(
37
- SELECT
38
- preferences.id AS rule_id,
39
- settings.id AS setting_id,
40
- sets.id AS set_id,
41
- sets.left_id AS anchor_id,
42
- sets.right_id AS set_tag_id,
43
- users.id AS user_id
44
- FROM cards preferences
45
- JOIN cards user_sets ON preferences.left_id = user_sets.id
46
- JOIN cards settings ON preferences.right_id = settings.id
47
- JOIN cards users ON user_sets.right_id = users.id
48
- JOIN cards sets ON user_sets.left_id = sets.id
49
- WHERE sets.type_id = #{SetID}
50
- AND settings.type_id = #{SettingID}
51
- AND (%s or users.codename = 'all')
52
- AND sets.trash is false
53
- AND settings.trash is false
54
- AND users.trash is false
55
- AND user_sets.trash is false
56
- AND preferences.trash is false;
57
- )
58
1
 
59
2
  def is_rule?
60
3
  is_standard_rule? || is_preference?
@@ -96,8 +39,9 @@ def rule_card_id setting_code, options={}
96
39
  end
97
40
 
98
41
  rule_set_keys.each do |rule_set_key|
99
- rule_id = self.class.rule_cache["#{rule_set_key}+#{setting_code}"]
100
- rule_id ||= fallback && self.class.rule_cache["#{rule_set_key}+#{fallback}"]
42
+ rule_cache = Card::Rule.rule_cache
43
+ rule_id = rule_cache["#{rule_set_key}+#{setting_code}"]
44
+ rule_id ||= fallback && rule_cache["#{rule_set_key}+#{fallback}"]
101
45
  return rule_id if rule_id
102
46
  end
103
47
  nil
@@ -120,172 +64,3 @@ def related_sets with_self=false
120
64
  end
121
65
  sets
122
66
  end
123
-
124
- module ClassMethods
125
- # User-specific rule use the pattern
126
- # user+set+setting
127
- def preference_sql user_id=nil
128
- user_restriction =
129
- if user_id
130
- "users.id = #{user_id}"
131
- else
132
- "users.type_id = #{UserID}"
133
- end
134
- PREFERENCE_SQL % user_restriction
135
- end
136
-
137
- def global_setting name
138
- Auth.as_bot do
139
- (card = Card[name]) && !card.db_content.strip.empty? && card.db_content
140
- end
141
- end
142
-
143
- def toggle val
144
- val.to_s.strip == "1"
145
- end
146
-
147
- def rule_cache_key row
148
- return false unless (setting_code = Card::Codename[row["setting_id"].to_i])
149
-
150
- anchor_id = row["anchor_id"]
151
- set_class_id = anchor_id.nil? ? row["set_id"] : row["set_tag_id"]
152
- return false unless (set_class_code = Card::Codename[set_class_id.to_i])
153
-
154
- [anchor_id, set_class_code, setting_code].compact.map(&:to_s) * "+"
155
- end
156
-
157
- def interpret_simple_rules
158
- ActiveRecord::Base.connection.select_all(RULE_SQL).each do |row|
159
- next unless (key = rule_cache_key row)
160
- @rule_hash[key] = row["rule_id"].to_i
161
- end
162
- end
163
-
164
- def interpret_preferences
165
- ActiveRecord::Base.connection.select_all(preference_sql).each do |row|
166
- next unless (key = rule_cache_key row) && (user_id = row["user_id"])
167
- add_preference_hash_values key, row["rule_id"].to_i, user_id.to_i
168
- end
169
- end
170
-
171
- def add_preference_hash_values key, rule_id, user_id
172
- @rule_hash[preference_key(key, user_id)] = rule_id
173
- @user_ids_hash[key] ||= []
174
- @user_ids_hash[key] << user_id
175
- @rule_keys_hash[user_id] ||= []
176
- @rule_keys_hash[user_id] << key
177
- end
178
-
179
- def cached_rule_keys_for user_id
180
- rule_keys_cache[user_id] || []
181
- end
182
-
183
- def all_user_ids_with_rule_for set_card, setting_code
184
- key =
185
- if (l = set_card.left) && (r = set_card.right)
186
- set_class_code = Card::Codename[r.id]
187
- "#{l.id}+#{set_class_code}+#{setting_code}"
188
- else
189
- set_class_code = Card::Codename[set_card.id]
190
- "#{set_class_code}+#{setting_code}"
191
- end
192
- user_ids = user_ids_cache[key] || []
193
- if user_ids.include? AllID # rule for all -> return all user ids
194
- Card.where(type_id: UserID).pluck(:id)
195
- else
196
- user_ids
197
- end
198
- end
199
-
200
- def preference_names user_name, setting_code
201
- Card.search(
202
- { right: { codename: setting_code },
203
- left: {
204
- left: { type_id: SetID }, right: user_name
205
- },
206
- return: :name }, "preference cards for user: #{user_name}"
207
- )
208
- end
209
-
210
- def preference_cards user_name, setting_code
211
- preference_names(user_name, setting_code).map { |name| Card.fetch name }
212
- end
213
-
214
- def rule_cache
215
- Card.cache.read("RULES") || begin
216
- @rule_hash = {}
217
- @user_ids_hash = {}
218
- @rule_keys_hash = {}
219
-
220
- interpret_simple_rules
221
- interpret_preferences
222
-
223
- write_user_ids_cache @user_ids_hash
224
- write_rule_keys_cache @rule_keys_hash
225
- write_rule_cache @rule_hash
226
- end
227
- end
228
-
229
- def preference_key key, user_id
230
- "#{key}+#{user_id}"
231
- end
232
-
233
- # all users that have a user-specific rule for a given rule key
234
- def user_ids_cache
235
- Card.cache.read("USER_IDS") || begin
236
- clear_rule_cache
237
- rule_cache
238
- @user_ids_hash
239
- end
240
- end
241
-
242
- # all keys of user-specific rules for a given user
243
- def rule_keys_cache
244
- Card.cache.read("RULE_KEYS") || begin
245
- clear_rule_cache
246
- rule_cache
247
- @rule_keys_hash
248
- end
249
- end
250
-
251
- def clear_rule_cache
252
- write_rule_cache nil
253
- write_user_ids_cache nil
254
- write_rule_keys_cache nil
255
- end
256
-
257
- def clear_preference_cache
258
- # FIXME: too entwined!
259
- clear_rule_cache
260
- end
261
-
262
- def write_rule_cache hash
263
- Card.cache.write "RULES", hash
264
- end
265
-
266
- def write_user_ids_cache hash
267
- Card.cache.write "USER_IDS", hash
268
- end
269
-
270
- def write_rule_keys_cache hash
271
- Card.cache.write "RULE_KEYS", hash
272
- end
273
-
274
- def read_rule_cache
275
- Card.cache.read("READRULES") || begin
276
- hash = {}
277
- Card.connection.select_all(
278
- Card::Set::All::Rules::READ_RULE_SQL
279
- ).each do |row|
280
- party_id = row["party_id"].to_i
281
- hash[party_id] ||= []
282
- hash[party_id] << row["read_rule_id"].to_i
283
- end
284
- Card.cache.write "READRULES", hash
285
- end
286
- end
287
-
288
- def clear_read_rule_cache
289
- Card.cache.write "READRULES", nil
290
- end
291
- end
@@ -9,8 +9,9 @@ format :html do
9
9
  card.each_item_name_with_options(_render_raw) do |name, options|
10
10
  construct_tab tabs, name, options
11
11
  end
12
- lazy_loading_tabs tabs[:paths], tabs[:active][:name],
13
- tabs[:active][:content], type: tab_type
12
+ tabs tabs[:paths], tabs[:active][:name], tab_type: tab_type, load: :lazy do
13
+ tabs[:active][:content]
14
+ end
14
15
  end
15
16
 
16
17
  def construct_tab tabs, name, explicit_options
@@ -45,6 +46,6 @@ format :html do
45
46
  card.item_cards.each do |item|
46
47
  tabs[item.name] = nest item, item_view_options(args)
47
48
  end
48
- static_tabs tabs, tab_type
49
+ tabs tabs, nil, tab_type: tab_type
49
50
  end
50
51
  end
@@ -3,7 +3,7 @@
3
3
  # the reference stuff. we need to organize a bit!
4
4
 
5
5
  event :update_rule_cache, :finalize, when: :is_rule? do
6
- self.class.clear_rule_cache
6
+ Card::Rule.clear_rule_cache
7
7
  end
8
8
 
9
9
  event :expire_related, :finalize do
@@ -28,6 +28,5 @@ def prototype_args anchor
28
28
  end
29
29
 
30
30
  def anchor_name card
31
- type_name = card.left(new: {})&.type_name || Card.default_type_id.cardname
32
- "#{type_name}+#{card.name.tag}"
31
+ "#{left_type(card)}+#{card.name.tag}"
33
32
  end
@@ -192,16 +192,16 @@ RSpec.describe Card::Set::All::EventConditions do
192
192
  end
193
193
  end
194
194
 
195
- specify "skip_event condition" do
195
+ specify "skip condition" do
196
196
  expect_skipping({ content: "changed" }, [], "A executed", for_name: "A")
197
197
  end
198
198
 
199
- specify "skip_event condition in subcard" do
199
+ specify "skip condition in subcard" do
200
200
  expect_skipping({ content: "changed", subcards: { "+B" => "changed +B" } },
201
201
  [], "A+B executed", for_name: "A+B")
202
202
  end
203
203
 
204
- specify "skip_event_in_action condition" do
204
+ specify "skip_in_action condition" do
205
205
  expect_skipping({ content: "changed", subcards: { "+B" => "changed +B" } },
206
206
  ["A+B executed"],
207
207
  ["A executed", "A+B executed", "A+B executed"],
@@ -8,6 +8,12 @@ RSpec.describe Card::Set::All::FetchHelper do
8
8
  Card.send :retrieve_existing, "A".to_name, opts
9
9
  end
10
10
 
11
+ describe "#controller fetch" do
12
+ it "removes underscores from new card names" do
13
+ expect(Card.controller_fetch(mark: "no_un_der_score").name).to eq("no un der score")
14
+ end
15
+ end
16
+
11
17
  describe "retrieve_existing" do
12
18
  it "looks for non-cached card in database" do
13
19
  expect_db_retrieval_with(:key, "a", nil) { retrieve }
@@ -49,5 +49,14 @@ RSpec.describe Card::Set::All::References do
49
49
  Card["A"].update! name: "AAA", update_referers: true
50
50
  expect(Card["X"].content).to eq("[[AAA]] [[AAA+B]] [[T]]")
51
51
  end
52
+
53
+ # FIXME: following should pass!
54
+ xit "handles reference loops" do
55
+ Card["A"].update! content: "[[A+B]] refers to me"
56
+ Card["A+B"].update! content: "[[A]] refers to me, too"
57
+ Card["A"].update! name: "AAA", update_referers: true
58
+ expect(Card["AAA+B"].content).to eq("[[AAA]] refers to me, too")
59
+ expect(Card["AAA"].content).to eq("[[AAA+B]] refers to me")
60
+ end
52
61
  end
53
62
  end