card 1.16.14 → 1.16.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/db/migrate_core_cards/20150903130006_attachment_upload_cards.rb +4 -2
  4. data/lib/card/auth.rb +15 -10
  5. data/lib/card/codename.rb +25 -21
  6. data/lib/card/content.rb +100 -68
  7. data/lib/card/format.rb +158 -129
  8. data/lib/card/query.rb +15 -9
  9. data/lib/card/query/attributes.rb +41 -49
  10. data/lib/card/set.rb +15 -12
  11. data/lib/card/set_pattern.rb +4 -5
  12. data/lib/card/spec_helper.rb +54 -16
  13. data/lib/cardio.rb +43 -25
  14. data/mod/01_core/chunk/include.rb +1 -1
  15. data/mod/01_core/set/all/collection.rb +76 -73
  16. data/mod/01_core/set/all/content.rb +0 -4
  17. data/mod/01_core/set/all/fetch.rb +35 -42
  18. data/mod/01_core/set/all/name.rb +17 -7
  19. data/mod/01_core/set/all/pattern.rb +12 -11
  20. data/mod/01_core/set/all/permissions.rb +51 -42
  21. data/mod/01_core/set/all/phases.rb +2 -1
  22. data/mod/01_core/set/all/references.rb +2 -2
  23. data/mod/01_core/set/all/rules.rb +28 -35
  24. data/mod/01_core/set/all/subcards.rb +12 -12
  25. data/mod/01_core/set/all/tracked_attributes.rb +1 -1
  26. data/mod/01_core/set/all/type.rb +11 -11
  27. data/mod/01_core/set/all/utils.rb +6 -1
  28. data/mod/01_core/spec/set/all/fetch_spec.rb +6 -6
  29. data/mod/01_core/spec/set/all/permissions_spec.rb +11 -11
  30. data/mod/01_core/spec/set/all/tracked_attributes_spec.rb +1 -1
  31. data/mod/01_history/lib/card/action.rb +52 -47
  32. data/mod/01_history/set/all/actions.rb +20 -16
  33. data/mod/01_history/set/all/history.rb +18 -13
  34. data/mod/02_basic_types/set/all/base.rb +23 -2
  35. data/mod/02_basic_types/set/type/pointer.rb +45 -36
  36. data/mod/02_basic_types/spec/set/all/base_spec.rb +40 -24
  37. data/mod/02_basic_types/spec/set/type/pointer_spec.rb +87 -0
  38. data/mod/03_machines/set/right/machine_output.rb +10 -6
  39. data/mod/04_settings/set/abstract/permission.rb +10 -5
  40. data/mod/04_settings/set/type/setting.rb +4 -1
  41. data/mod/05_email/set/all/follow.rb +39 -44
  42. data/mod/05_email/set/all/notify.rb +4 -1
  43. data/mod/05_email/set/right/followers.rb +16 -14
  44. data/mod/05_email/set/self/follow_defaults.rb +22 -19
  45. data/mod/05_standard/lib/carrier_wave/cardmount.rb +1 -0
  46. data/mod/05_standard/set/abstract/attachment.rb +85 -58
  47. data/mod/05_standard/set/all/comment.rb +35 -19
  48. data/mod/05_standard/set/all/error.rb +124 -98
  49. data/mod/05_standard/set/all/list_changes.rb +27 -22
  50. data/mod/05_standard/set/all/rich_html/editing.rb +96 -70
  51. data/mod/05_standard/set/all/rich_html/form.rb +123 -81
  52. data/mod/05_standard/set/all/rich_html/modal.rb +15 -58
  53. data/mod/05_standard/set/right/account.rb +2 -2
  54. data/mod/05_standard/set/right/email.rb +3 -2
  55. data/mod/05_standard/set/rstar/rules.rb +3 -3
  56. data/mod/05_standard/set/self/search.rb +45 -22
  57. data/mod/05_standard/set/type/cardtype.rb +13 -11
  58. data/mod/05_standard/set/type/listed_by.rb +3 -2
  59. data/mod/05_standard/set/type/set.rb +17 -13
  60. data/mod/05_standard/set/type/signup.rb +1 -2
  61. data/mod/05_standard/set/type/user.rb +1 -1
  62. data/mod/05_standard/spec/set/all/account_spec.rb +1 -1
  63. data/mod/05_standard/spec/set/all/history_spec.rb +1 -1
  64. data/mod/05_standard/spec/set/type/email_template_spec.rb +140 -134
  65. data/mod/05_standard/spec/set/type/image_spec.rb +2 -1
  66. data/mod/05_standard/spec/set/type/signup_spec.rb +2 -2
  67. data/spec/models/card/trash_spec.rb +1 -1
  68. data/spec/spec_helper.rb +0 -1
  69. metadata +2 -2
@@ -4,14 +4,18 @@ class Card
4
4
  class Format
5
5
  include Card::Location
6
6
 
7
- DEPRECATED_VIEWS = { view: :open, card: :open, line: :closed, bare: :core, naked: :core }
7
+ DEPRECATED_VIEWS = { view: :open, card: :open, line: :closed,
8
+ bare: :core, naked: :core }
8
9
  INCLUSION_MODES = { closed: :closed, closed_content: :closed, edit: :edit,
9
- layout: :layout, new: :edit, setup: :edit, normal: :normal, template: :template } #should be set in views
10
+ layout: :layout, new: :edit, setup: :edit,
11
+ normal: :normal, template: :template }
12
+ # FIXME: should be set in views
10
13
 
11
14
  cattr_accessor :ajax_call, :registered
12
- [ :perms, :denial_views, :closed_views, :error_codes, :view_tags, :aliases ].each do |acc|
13
- cattr_accessor acc
14
- self.send "#{acc}=", {}
15
+ [:perms, :denial_views, :closed_views, :error_codes, :view_tags, :aliases
16
+ ].each do |accessor_name|
17
+ cattr_accessor accessor_name
18
+ send "#{accessor_name}=", {}
15
19
  end
16
20
 
17
21
  attr_reader :card, :root, :parent, :main_opts
@@ -27,8 +31,8 @@ class Card
27
31
  def format_class_name format
28
32
  format = format.to_s
29
33
  format = '' if format == 'base'
30
- format = @@aliases[ format ] if @@aliases[ format ]
31
- "#{ format.camelize }Format"
34
+ format = @@aliases[format] if @@aliases[format]
35
+ "#{format.camelize}Format"
32
36
  end
33
37
 
34
38
  def extract_class_vars view, opts
@@ -37,32 +41,35 @@ class Card
37
41
  error_codes[view] = opts.delete(:error_code) if opts[:error_code]
38
42
  denial_views[view] = opts.delete(:denial) if opts[:denial]
39
43
  closed_views[view] = opts.delete(:closed) if opts[:closed]
44
+ extract_view_tags view, opts
45
+ end
40
46
 
41
- if tags = opts.delete(:tags)
42
- Array.wrap(tags).each do |tag|
43
- view_tags[view] ||= {}
44
- view_tags[view][tag] = true
45
- end
47
+ def extract_view_tags view, opts
48
+ tags = opts.delete :tags
49
+ return unless tags
50
+ Array.wrap(tags).each do |tag|
51
+ view_tags[view] ||= {}
52
+ view_tags[view][tag] = true
46
53
  end
47
-
48
54
  end
49
55
 
50
56
  def new card, opts={}
51
57
  if self != Format
52
58
  super
53
59
  else
54
- klass = Card.const_get format_class_name( opts[:format] || :html )
55
- self == klass ? super : klass.new( card, opts )
60
+ format = opts[:format] || :html
61
+ klass = Card.const_get format_class_name(format)
62
+ self == klass ? super : klass.new(card, opts)
56
63
  end
57
64
  end
58
65
 
59
66
  def tagged view, tag
60
- view and tag and view_tags = @@view_tags[view.to_sym] and view_tags[tag.to_sym]
67
+ return unless view && tag && (view_tags = @@view_tags[view.to_sym])
68
+ view_tags[tag.to_sym]
61
69
  end
62
70
 
63
-
64
71
  def format_ancestry
65
- ancestry = [ self ]
72
+ ancestry = [self]
66
73
  unless self == Card::Format
67
74
  ancestry = ancestry + superclass.format_ancestry
68
75
  end
@@ -74,18 +81,19 @@ class Card
74
81
  end
75
82
  end
76
83
 
77
-
78
- #~~~~~ INSTANCE METHODS
84
+ # ~~~~~ INSTANCE METHODS
79
85
 
80
86
  def initialize card, opts={}
81
- @card = card or raise Card::Error, "format initialized without card"
87
+ unless (@card = card)
88
+ raise Card::Error, 'format initialized without card'
89
+ end
82
90
  opts.each do |key, value|
83
91
  instance_variable_set "@#{key}", value
84
92
  end
85
93
 
86
- @mode ||= :normal
94
+ @mode ||= :normal
95
+ @root ||= self
87
96
  @depth ||= 0
88
- @root ||= self
89
97
 
90
98
  @context_names = get_context_names
91
99
  include_set_format_modules
@@ -106,8 +114,8 @@ class Card
106
114
  end
107
115
 
108
116
  def include_set_format_modules
109
- self.class.format_ancestry.reverse.each do |klass|
110
- card.set_format_modules( klass ).each do |m|
117
+ self.class.format_ancestry.reverse_each do |klass|
118
+ card.set_format_modules(klass).each do |m|
111
119
  singleton_class.send :include, m
112
120
  end
113
121
  end
@@ -121,7 +129,7 @@ class Card
121
129
  end
122
130
  end
123
131
 
124
- def get_inclusion_defaults nested_card
132
+ def get_inclusion_defaults _nested_card
125
133
  { view: :name }
126
134
  end
127
135
 
@@ -146,12 +154,12 @@ class Card
146
154
  end
147
155
 
148
156
  def with_name_context name
149
- old_context = @context_names
150
- add_name_context name
151
- result = yield
152
- @context_names = old_context
153
- result
154
- end
157
+ old_context = @context_names
158
+ add_name_context name
159
+ result = yield
160
+ @context_names = old_context
161
+ result
162
+ end
155
163
 
156
164
  def main?
157
165
  @depth == 0
@@ -168,7 +176,7 @@ class Card
168
176
  def template
169
177
  @template ||= begin
170
178
  c = controller
171
- t = ActionView::Base.new c.class.view_paths, {_routes: c._routes}, c
179
+ t = ActionView::Base.new c.class.view_paths, { _routes: c._routes }, c
172
180
  t.extend c.class._helpers
173
181
  t
174
182
  end
@@ -179,16 +187,16 @@ class Card
179
187
  when /(_)?(optional_)?render(_(\w+))?/
180
188
  view = $3 ? $4 : opts.shift
181
189
  args = opts[0] ? opts.shift.clone : {}
182
- args.merge!( optional: true, default_visibility: opts.shift) if $2
183
- args[ :skip_permissions ] = true if $1
190
+ args.merge!(optional: true, default_visibility: opts.shift) if $2
191
+ args[:skip_permissions] = true if $1
184
192
  render view, args
185
- when /^_view_(\w+)/
186
- view = @current_view || $1
187
- unsupported_view view
193
+ # when /^_view_(\w+)/
194
+ # view = @current_view || $1
195
+ # unsupported_view view
188
196
  else
189
197
  proc = proc { |*a| raw yield *a } if proc
190
198
  response = root.template.send method, *opts, &proc
191
- String===response ? root.template.raw( response ) : response
199
+ response.is_a?(String) ? root.template.raw(response) : response
192
200
  end
193
201
  end
194
202
 
@@ -196,83 +204,88 @@ class Card
196
204
  # ---------- Rendering ------------
197
205
  #
198
206
 
199
-
200
-
201
207
  def render view, args={}
202
- unless args.delete(:optional) && !show_view?( view, args )
203
- @current_view = view = ok_view canonicalize_view( view ), args
204
- args = default_render_args view, args
205
- with_inclusion_mode view do
206
- Card::ViewCache.fetch(self, view, args) do
207
- method = method "_view_#{ view }"
208
- method.arity == 0 ? method.call : method.call(args)
209
- end
208
+ view = canonicalize_view view
209
+ return if hidden_view? view, args
210
+ @current_view = view = ok_view view, args
211
+ args = default_render_args view, args
212
+ with_inclusion_mode view do
213
+ Card::ViewCache.fetch(self, view, args) do
214
+ method = view_method view, args
215
+ method.arity == 0 ? method.call : method.call(args)
210
216
  end
211
217
  end
212
218
  rescue => e
213
219
  rescue_view e, view
214
220
  end
215
221
 
222
+ def view_method view, args
223
+ method "_view_#{view}"
224
+ rescue
225
+ args[:unsupported_view] = view
226
+ method '_view_unsupported_view'
227
+ end
228
+
229
+ def hidden_view? view, args
230
+ args.delete(:optional) && !show_view?(view, args)
231
+ end
216
232
 
217
233
  def show_view? view, args
218
- default = args.delete(:default_visibility) || :show #FIXME - ugly
219
- view_key = canonicalize_view view
220
- api_option = args["optional_#{ view_key }".to_sym]
234
+ default = args.delete(:default_visibility) || :show # FIXME: - ugly
235
+ api_option = args["optional_#{view}".to_sym]
221
236
  case
222
- # args remove option
223
- when api_option == :always ; true
224
- when api_option == :never ; false
225
- # wagneer's choice
226
- when show_views( args ).member?( view_key ) ; true
227
- when hide_views( args ).member?( view_key ) ; false
228
- # args override default
229
- when api_option == :show ; true
230
- when api_option == :hide ; false
231
- # default
232
- else ; default==:show
237
+ # permanent visibility specified in code
238
+ when api_option == :always then true
239
+ when api_option == :never then false
240
+ else
241
+ # wagneer can override code settings
242
+ contextual_setting = nest_arg_visibility(view, args) || api_option
243
+ case contextual_setting
244
+ when :show then true
245
+ when :hide then false
246
+ else default == :show
247
+ end
233
248
  end
234
249
  end
235
250
 
236
- def show_views args
237
- parse_view_visibility args[:show]
238
- end
239
-
240
- def hide_views args
241
- parse_view_visibility args[:hide]
251
+ def nest_arg_visibility view, args
252
+ [:show, :hide].each do |setting|
253
+ return setting if parse_view_visibility(args[setting]).member?(view)
254
+ end
255
+ false
242
256
  end
243
257
 
244
258
  def parse_view_visibility val
245
259
  case val
246
- when Array; val
247
- when String; val.split(/[\s,]+/)
248
- when NilClass; []
260
+ when NilClass then []
261
+ when Array then val
262
+ when String then val.split(/[\s,]+/)
249
263
  else raise Card::Error, "bad show/hide argument: #{val}"
250
- end.map{ |view| canonicalize_view view }
264
+ end.map { |view| canonicalize_view view }
251
265
  end
252
266
 
253
-
254
267
  def default_render_args view, a=nil
255
- args = case a
256
- when nil ; {}
257
- when Hash ; a.clone
258
- when Array ; a[0].merge a[1]
259
- else ; raise Card::Error, "bad render args: #{a}"
260
- end
268
+ args =
269
+ case a
270
+ when nil then {}
271
+ when Hash then a.clone
272
+ when Array then a[0].merge a[1]
273
+ else raise Card::Error, "bad render args: #{a}"
274
+ end
261
275
 
262
- view_key = canonicalize_view view
263
- default_method = "default_#{ view }_args"
276
+ default_method = "default_#{view}_args"
264
277
  if respond_to? default_method
265
278
  send default_method, args
266
279
  end
267
280
  args
268
281
  end
269
282
 
270
-
271
283
  def rescue_view e, view
272
284
  if Rails.env =~ /^cucumber|test$/
273
285
  raise e
274
286
  else
275
- Rails.logger.info "\nError rendering #{error_cardname} / #{view}: #{e.class} : #{e.message}"
287
+ Rails.logger.info "\nError rendering #{error_cardname} / #{view}: "\
288
+ "#{e.class} : #{e.message}"
276
289
  Card::Error.current = e
277
290
  card.notable_exception_raised
278
291
  if (debug = Card[:debugger]) && debug.content == 'on'
@@ -287,11 +300,7 @@ class Card
287
300
  card && card.name.present? ? card.name : 'unknown card'
288
301
  end
289
302
 
290
- def unsupported_view view
291
- "view (#{view}) not supported for #{error_cardname}"
292
- end
293
-
294
- def rendering_error exception, view
303
+ def rendering_error _exception, view
295
304
  "Error rendering: #{error_cardname} (#{view} view)"
296
305
  end
297
306
 
@@ -300,14 +309,16 @@ class Card
300
309
  #
301
310
 
302
311
  def subformat subcard
303
- subcard = Card.fetch( subcard, new: {} ) if String===subcard
304
- sub = self.class.new subcard, parent: self, depth: @depth+1, root: @root,
305
- # FIXME - the following four should not be hard-coded here. need a generalized mechanism
306
- # for attribute inheritance
307
- context_names: @context_names, mode: @mode, mainline: @mainline, form: @form
312
+ subcard = Card.fetch(subcard, new: {}) if subcard.is_a?(String)
313
+ self.class.new subcard,
314
+ parent: self, depth: @depth + 1, root: @root,
315
+ # FIXME: - the following four should not be hard-coded
316
+ # here. need a generalized mechanism
317
+ # for attribute inheritance
318
+ context_names: @context_names, mode: @mode,
319
+ mainline: @mainline, form: @form
308
320
  end
309
321
 
310
-
311
322
  def process_content content=nil, opts={}
312
323
  process_content_object(content, opts).to_s
313
324
  end
@@ -315,31 +326,47 @@ class Card
315
326
  def process_content_object content=nil, opts={}
316
327
  return content unless card
317
328
  content = card.raw_content || '' if content.nil?
318
-
319
- obj_content = Card::Content===content ? content : Card::Content.new( content, format=self, opts.delete(:content_opts) )
320
- card.update_references( obj_content, refresh=true ) if card.references_expired # I thik we need this generalized
321
- obj_content.process_content_object do |chunk_opts|
329
+ content_object = get_content_object content, opts
330
+ if card.references_expired
331
+ # FIXME: should be handled with method on Card
332
+ card.update_references content_object, true
333
+ end
334
+ content_object.process_content_object do |chunk_opts|
322
335
  prepare_nest chunk_opts.merge(opts) { yield }
323
336
  end
324
337
  end
325
338
 
339
+ def get_content_object content, opts
340
+ if content.is_a? Content
341
+ content
342
+ else
343
+ Content.new content, self, opts.delete(:content_opts)
344
+ end
345
+ end
346
+
326
347
  def ok_view view, args={}
327
348
  return view if args.delete :skip_permissions
328
- approved_view = case
329
- when @depth >= Card.config.max_depth # prevent recursion. @depth tracks subformats
349
+ approved_view =
350
+ case
351
+ when @depth >= Card.config.max_depth
352
+ # prevent recursion. @depth tracks subformats
330
353
  :too_deep
331
- when @@perms[view] == :none # permission skipping specified in view definition
354
+ when @@perms[view] == :none
355
+ # permission skipping specified in view definition
332
356
  view
333
- when args.delete(:skip_permissions) # permission skipping specified in args
357
+ when args.delete(:skip_permissions)
358
+ # permission skipping specified in args
334
359
  view
335
- when !card.known? && !tagged(view, :unknown_ok) # handle unknown cards (where view not exempt)
360
+ when !card.known? && !tagged(view, :unknown_ok)
361
+ # handle unknown cards (where view not exempt)
336
362
  view_for_unknown view, args
337
- else # run explicit permission checks
363
+ else
364
+ # run explicit permission checks
338
365
  permitted_view view, args
339
366
  end
340
367
 
341
368
  args[:denied_view] = view if approved_view != view
342
- if focal? && error_code = @@error_codes[ approved_view ]
369
+ if focal? && (error_code = @@error_codes[approved_view])
343
370
  root.error_status = error_code
344
371
  end
345
372
  approved_view
@@ -372,20 +399,19 @@ class Card
372
399
  @ok[task]
373
400
  end
374
401
 
375
- def view_for_unknown view, args
402
+ def view_for_unknown _view, _args
376
403
  # note: overridden in HTML
377
404
  focal? ? :not_found : :missing
378
405
  end
379
406
 
380
407
  def canonicalize_view view
381
- unless view.blank?
382
- view_key = view.to_viewname.key.to_sym
383
- DEPRECATED_VIEWS[view_key] || view_key
384
- end
408
+ return if view.blank?
409
+ view_key = view.to_viewname.key.to_sym
410
+ DEPRECATED_VIEWS[view_key] || view_key
385
411
  end
386
412
 
387
413
  def with_inclusion_mode mode
388
- if switch_mode = INCLUSION_MODES[ mode ] and @mode != switch_mode
414
+ if (switch_mode = INCLUSION_MODES[mode]) && @mode != switch_mode
389
415
  old_mode, @mode = @mode, switch_mode
390
416
  @inclusion_defaults = nil
391
417
  end
@@ -402,13 +428,17 @@ class Card
402
428
  opts ||= {}
403
429
 
404
430
  case
405
- when opts.has_key?(:comment) # commented nest
431
+ when opts.has_key?(:comment)
432
+ # commented nest
406
433
  opts[:comment]
407
- when @mode == :closed && @char_count > Card.config.max_char_count # move on; content out of view
434
+ when @mode == :closed && @char_count > Card.config.max_char_count
435
+ # move on; content out of view
408
436
  ''
409
- when opts[:inc_name] == '_main' && show_layout? && @depth==0 # the main card within a layout
437
+ when opts[:inc_name] == '_main' && show_layout? && @depth == 0
438
+ # the main card within a layout
410
439
  expand_main opts
411
- else # standard nest
440
+ else
441
+ # standard nest
412
442
  result = nest fetch_nested_card(opts), opts
413
443
  @char_count += result.length if @mode == :closed && result
414
444
  result
@@ -419,27 +449,26 @@ class Card
419
449
  opts.merge! root.main_opts if root.main_opts
420
450
  legacy_main_opts_tweaks! opts
421
451
 
422
- #opts[:view] ||= :open
423
452
  with_inclusion_mode :normal do
424
453
  @mainline = true
425
- result = wrap_main nest( root.card, opts )
454
+ result = wrap_main nest(root.card, opts)
426
455
  @mainline = false
427
456
  result
428
457
  end
429
458
  end
430
459
 
431
460
  def legacy_main_opts_tweaks! opts
432
- if val=params[:size] and val.present?
461
+ if (val = params[:size]) && val.present?
433
462
  opts[:size] = val.to_sym
434
463
  end
435
464
 
436
- if val=params[:item] and val.present?
465
+ if (val = params[:item]) && val.present?
437
466
  opts[:items] = (opts[:items] || {}).reverse_merge view: val.to_sym
438
467
  end
439
468
  end
440
469
 
441
470
  def wrap_main content
442
- content #no wrapping in base format
471
+ content # no wrapping in base format
443
472
  end
444
473
 
445
474
  def nest nested_card, opts={}
@@ -497,23 +526,24 @@ class Card
497
526
 
498
527
  # CLEANME This is a hack so plus cards re-populate on failed signups
499
528
  p = params['subcards']
500
- if p && card_params = p[cardname.to_s]
529
+ if p && (card_params = p[cardname.to_s])
501
530
  content = card_params['content']
502
531
  end
503
- content if content.present? # why is this necessary? - efm
504
- # probably for blanks? -- older/wiser efm
532
+ content if content.present? # returns nil for empty string
505
533
  end
506
534
 
507
535
  def fetch_nested_card options
508
536
  args = { name: options[:inc_name], type: options[:type], supercard: card }
509
- args.delete(:supercard) if options[:inc_name].strip.blank? # special case. gets absolutized incorrectly. fix in smartname?
537
+ args.delete(:supercard) if options[:inc_name].strip.blank?
538
+ # special case. gets absolutized incorrectly. fix in smartname?
510
539
  if options[:inc_name] =~ /^_main\+/
511
- # FIXME this is a rather hacky (and untested) way to get @superleft to work on new cards named _main+whatever
540
+ # FIXME: this is a rather hacky (and untested) way to get @superleft
541
+ # to work on new cards named _main+whatever
512
542
  args[:name] = args[:name].gsub /^_main\+/, '+'
513
543
  args[:supercard] = root.card
514
544
  end
515
- if content=get_inclusion_content(options[:inc_name])
516
- args[:content]=content
545
+ if (content = get_inclusion_content options[:inc_name])
546
+ args[:content] = content
517
547
  end
518
548
  Card.fetch options[:inc_name], new: args
519
549
  end
@@ -552,4 +582,3 @@ class Card
552
582
  end
553
583
  end
554
584
  end
555
-