card 1.93.3 → 1.93.4

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.
Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/db/migrate/20170908114452_increase_text_size_for_delayed_jobs.rb +9 -0
  4. data/db/migrate_core_cards/data/cards/*header +2 -2
  5. data/lib/card/format/nest.rb +12 -5
  6. data/lib/card/format/nest/fetch.rb +1 -2
  7. data/lib/card/format/render.rb +2 -2
  8. data/lib/card/model/save_helper.rb +1 -1
  9. data/lib/card/set/format/haml_views.rb +7 -3
  10. data/lib/card/subcards.rb +27 -228
  11. data/lib/card/subcards/add.rb +121 -0
  12. data/lib/card/subcards/relate.rb +27 -0
  13. data/lib/card/subcards/remove.rb +42 -0
  14. data/lib/card/tasks/card/create.rake +35 -132
  15. data/lib/card/tasks/card/file_card_creator.rb +25 -0
  16. data/lib/card/tasks/card/file_card_creator/abstract_file_card.rb +44 -0
  17. data/lib/card/tasks/card/file_card_creator/abstract_file_card/migration_file.rb +49 -0
  18. data/lib/card/tasks/card/file_card_creator/abstract_file_card/ruby_file.rb +30 -0
  19. data/lib/card/tasks/card/file_card_creator/abstract_file_card/source_file.rb +36 -0
  20. data/lib/card/tasks/card/file_card_creator/haml_card.rb +42 -0
  21. data/lib/card/tasks/card/file_card_creator/output_helper.rb +50 -0
  22. data/lib/card/tasks/card/file_card_creator/script_card.rb +33 -0
  23. data/lib/card/tasks/card/file_card_creator/style_card.rb +25 -0
  24. data/lib/generators/card/template/template_generator.rb +1 -1
  25. data/mod/account/set/self/account_links.rb +1 -1
  26. data/mod/basic_formats/set/all/all_csv.rb +63 -0
  27. data/mod/basic_formats/set/all/json.rb +4 -1
  28. data/mod/bootstrap/db/migrate_cards/20170719163733_update_bootswatch_themes_to_4_beta.rb +5 -2
  29. data/mod/carrierwave/set/abstract/attachment.rb +1 -2
  30. data/mod/core/set/abstract/haml_file.rb +20 -0
  31. data/mod/core/set/all/chunk.rb +125 -0
  32. data/mod/core/set/all/collection.rb +2 -351
  33. data/mod/core/set/all/content.rb +26 -7
  34. data/mod/core/set/all/extended.rb +45 -0
  35. data/mod/core/set/all/haml.rb +3 -7
  36. data/mod/core/set/all/item.rb +92 -0
  37. data/mod/core/set/all/name.rb +36 -0
  38. data/mod/core/set/all/subcards.rb +21 -12
  39. data/mod/core/set/all/tabs.rb +50 -0
  40. data/mod/core/set/all/trash.rb +4 -0
  41. data/mod/core/spec/set/all/chunk_spec.rb +45 -0
  42. data/mod/core/spec/set/all/collection_spec.rb +6 -6
  43. data/mod/history/set/all/action_view.rb +1 -1
  44. data/mod/machines/lib/javascript/decko.js.coffee +3 -0
  45. data/mod/pointer/set/abstract/02_pointer/edit.rb +0 -2
  46. data/mod/search/set/abstract/search.rb +1 -1
  47. data/mod/search/set/all/filter.rb +0 -2
  48. data/mod/search/template/all/filter/_filter_input.haml +1 -1
  49. data/mod/search/template/all/filter/filter_form.haml +1 -1
  50. data/mod/standard/set/all/rich_html/editing.rb +1 -1
  51. data/mod/standard/set/all/rich_html/form.rb +6 -7
  52. data/mod/standard/set/all/rich_html/menu.rb +2 -3
  53. data/mod/standard/set/all/rich_html/toolbar.rb +3 -4
  54. data/mod/standard/set/type/cardtype.rb +1 -1
  55. data/mod/standard/spec/set/all/rich_html/editing_spec.rb +15 -4
  56. data/mod/tinymce_editor/db/migrate_cards/{20171113233150_update_tinymce_config.rb → 20171113233151_update_tinymce_config.rb} +1 -0
  57. metadata +25 -161
  58. data/.rspec +0 -4
  59. data/card.gemspec +0 -87
  60. data/db/seed/test/fixtures/.gitkeep +0 -0
  61. data/mod/bootstrap/vendor/bootstrap/.babelrc.js +0 -16
  62. data/mod/bootstrap/vendor/bootstrap/.editorconfig +0 -17
  63. data/mod/bootstrap/vendor/bootstrap/.eslintignore +0 -3
  64. data/mod/bootstrap/vendor/bootstrap/.gitattributes +0 -16
  65. data/mod/bootstrap/vendor/bootstrap/.github/CONTRIBUTING.md +0 -252
  66. data/mod/bootstrap/vendor/bootstrap/.github/ISSUE_TEMPLATE.md +0 -22
  67. data/mod/bootstrap/vendor/bootstrap/.gitignore +0 -46
  68. data/mod/bootstrap/vendor/bootstrap/.hound.yml +0 -19
  69. data/mod/bootstrap/vendor/bootstrap/.houndignore +0 -4
  70. data/mod/bootstrap/vendor/bootstrap/.travis.yml +0 -32
  71. data/mod/bootstrap/vendor/bootstrap/build/.htmllintrc +0 -19
  72. data/mod/bootstrap/vendor/bootstrap/build/.stylelintrc +0 -248
  73. data/mod/bootstrap/vendor/bootstrap/docs/4.0/examples/.stylelintrc +0 -12
  74. data/mod/bootstrap/vendor/bootstrap/js/.eslintrc.json +0 -240
  75. data/mod/bootstrap/vendor/bootstrap/js/tests/.eslintrc.json +0 -46
  76. data/mod/bootstrap/vendor/bootswatch/.gitignore +0 -7
  77. data/mod/bootstrap/vendor/bootswatch/.npmignore +0 -12
  78. data/mod/bootstrap/vendor/bootswatch/.travis.yml +0 -21
  79. data/mod/bootstrap/vendor/bootswatch/docs/.nojekyll +0 -0
  80. data/mod/bootstrap/vendor/bootswatch/docs/2/.travis.yml +0 -15
  81. data/mod/bootstrap/vendor/bootswatch/docs/2/bower_components/bootstrap/.bower.json +0 -20
  82. data/mod/bootstrap/vendor/bootswatch/docs/2/bower_components/bootstrap/.gitignore +0 -37
  83. data/mod/bootstrap/vendor/bootswatch/docs/2/bower_components/bootstrap/.travis.yml +0 -3
  84. data/mod/bootstrap/vendor/bootswatch/docs/2/bower_components/bootstrap/js/.jshintrc +0 -12
  85. data/mod/bootstrap/vendor/bootswatch/docs/2/bower_components/jquery/.bower.json +0 -20
  86. data/mod/bootstrap/vendor/bootswatch/docs/2/bower_components/jquery/.gitignore +0 -1
  87. data/mod/bootstrap/vendor/bootswatch/docs/2/swatchmaker/.gitignore +0 -1
  88. data/mod/bootstrap/vendor/bootswatch/docs/3/bower_components/bootstrap-sass-official/.bower.json +0 -45
  89. data/mod/bootstrap/vendor/bootswatch/docs/3/bower_components/bootstrap/.bower.json +0 -44
  90. data/mod/bootstrap/vendor/bootswatch/docs/3/bower_components/bootstrap/grunt/.jshintrc +0 -7
  91. data/mod/bootstrap/vendor/bootswatch/docs/3/bower_components/bootstrap/js/.jscsrc +0 -42
  92. data/mod/bootstrap/vendor/bootswatch/docs/3/bower_components/bootstrap/js/.jshintrc +0 -15
  93. data/mod/bootstrap/vendor/bootswatch/docs/3/bower_components/bootstrap/less/.csscomb.json +0 -304
  94. data/mod/bootstrap/vendor/bootswatch/docs/3/bower_components/bootstrap/less/.csslintrc +0 -19
  95. data/mod/bootstrap/vendor/bootswatch/docs/3/bower_components/font-awesome/.bower.json +0 -14
  96. data/mod/bootstrap/vendor/bootswatch/docs/3/bower_components/font-awesome/.gitignore +0 -32
  97. data/mod/bootstrap/vendor/bootswatch/docs/3/bower_components/html5shiv/.bower.json +0 -25
  98. data/mod/bootstrap/vendor/bootswatch/docs/3/bower_components/jquery/.bower.json +0 -38
  99. data/mod/bootstrap/vendor/bootswatch/docs/3/bower_components/respond/.bower.json +0 -20
  100. data/mod/bootstrap/vendor/select2/.editorconfig +0 -6
  101. data/mod/bootstrap/vendor/select2/.github/CONTRIBUTING.md +0 -204
  102. data/mod/bootstrap/vendor/select2/.github/ISSUE_TEMPLATE.md +0 -46
  103. data/mod/bootstrap/vendor/select2/.github/PULL_REQUEST_TEMPLATE.md +0 -13
  104. data/mod/bootstrap/vendor/select2/.gitignore +0 -3
  105. data/mod/bootstrap/vendor/select2/.jshintignore +0 -4
  106. data/mod/bootstrap/vendor/select2/.jshintrc +0 -25
  107. data/mod/bootstrap/vendor/select2/.travis.yml +0 -22
  108. data/script/fetch_bootswatch_themes.rb +0 -38
  109. data/spec/config/initializers/core_extensions_spec.rb +0 -47
  110. data/spec/config/initializers/patches/active_job_spec.rb +0 -7
  111. data/spec/lib/card/action_spec.rb +0 -15
  112. data/spec/lib/card/auth_spec.rb +0 -58
  113. data/spec/lib/card/cache_spec.rb +0 -116
  114. data/spec/lib/card/chunk_spec.rb +0 -18
  115. data/spec/lib/card/codename_spec.rb +0 -66
  116. data/spec/lib/card/content_spec.rb +0 -428
  117. data/spec/lib/card/diff_spec.rb +0 -208
  118. data/spec/lib/card/format/nest_spec.rb +0 -13
  119. data/spec/lib/card/format/render_spec.rb +0 -26
  120. data/spec/lib/card/format_spec.rb +0 -117
  121. data/spec/lib/card/i18n_spec.rb +0 -24
  122. data/spec/lib/card/loader/Modfile +0 -2
  123. data/spec/lib/card/loader_spec.rb +0 -98
  124. data/spec/lib/card/migration/import_spec.rb +0 -80
  125. data/spec/lib/card/mod/loader/mod_dirs.rb +0 -8
  126. data/spec/lib/card/mod/loader/set_loader_spec.rb +0 -19
  127. data/spec/lib/card/mod/loader/set_pattern_loader_spec.rb +0 -19
  128. data/spec/lib/card/name/fields_and_traits_spec.rb +0 -18
  129. data/spec/lib/card/name_spec.rb +0 -70
  130. data/spec/lib/card/query/sorting_spec.rb +0 -68
  131. data/spec/lib/card/query_spec.rb +0 -574
  132. data/spec/lib/card/reference_spec.rb +0 -212
  133. data/spec/lib/card/set/event_spec.rb +0 -22
  134. data/spec/lib/card/set/trait_spec.rb +0 -80
  135. data/spec/lib/card/set_pattern_spec.rb +0 -59
  136. data/spec/lib/card/set_spec.rb +0 -89
  137. data/spec/lib/card/stage_director_spec.rb +0 -482
  138. data/spec/lib/card/subcards_spec.rb +0 -177
  139. data/spec/lib/card/success_spec.rb +0 -148
  140. data/spec/lib/card/view_cache_spec.rb +0 -27
  141. data/spec/mailers/mailer_spec.rb +0 -62
  142. data/spec/models/card/create_spec.rb +0 -119
  143. data/spec/models/card/trash_spec.rb +0 -189
  144. data/spec/models/card_spec.rb +0 -136
  145. data/spec/spec_helper.rb +0 -45
  146. data/spec/support/card_spec_helper.rb +0 -74
  147. data/spec/support/card_spec_loader.rb +0 -112
  148. data/spec/support/helper/card_helper.rb +0 -58
  149. data/spec/support/helper/event_helper.rb +0 -94
  150. data/spec/support/helper/render_helper.rb +0 -44
  151. data/spec/support/helper/save_helper.rb +0 -30
  152. data/spec/support/helper/set_helper.rb +0 -80
  153. data/spec/support/matchers/card_matchers.rb +0 -160
  154. data/spec/support/matchers/expectations.rb +0 -5
  155. data/spec/support/matchers/file_matchers.rb +0 -71
  156. data/spec/support/matchers/html_matchers.rb +0 -29
  157. data/spec/support/matchers/negated_matchers.rb +0 -2
  158. data/spec/support/simplecov_helper.rb +0 -70
  159. data/spec/support/test_mods/mod1/set/all/test_set.rb +0 -3
  160. data/spec/support/test_mods/mod2/set_pattern/test_pattern.rb +0 -0
@@ -34,102 +34,10 @@ module ClassMethods
34
34
  end
35
35
  end
36
36
 
37
- def item_names _args={}
38
- format._render_raw.split(/[,\n]/)
39
- end
40
-
41
- def item_cards _args={} # FIXME: this is inconsistent with item_names
42
- [self]
43
- end
44
-
45
37
  def collection?
46
38
  item_cards != [self]
47
39
  end
48
40
 
49
- def item_type
50
- nil
51
- end
52
-
53
- def item_keys args={}
54
- item_names(args).map do |item|
55
- item.to_name.key
56
- end
57
- end
58
-
59
- def include_item? item
60
- key = item.is_a?(Card) ? item.name.key : item.to_name.key
61
- item_names.map { |name| name.to_name.key }.member? key
62
- end
63
-
64
- def add_item item
65
- return if include_item? item
66
- self.content = "#{content}\n#{name}"
67
- end
68
-
69
- def drop_item item
70
- return unless include_item? item
71
- new_names = item_names.reject { |i| i == item }
72
- self.content = new_names.empty? ? "" : new_names.join("\n")
73
- end
74
-
75
- def insert_item index, name
76
- new_names = item_names
77
- new_names.delete name
78
- new_names.insert index, name
79
- self.content = new_names.join "\n"
80
- end
81
-
82
- def add_id id
83
- add_item "~#{id}"
84
- end
85
-
86
- def drop_id id
87
- drop_item "~#{id}"
88
- end
89
-
90
- def insert_id index, id
91
- insert_item index, "~#{id}"
92
- end
93
-
94
- def extended_item_cards context=nil
95
- context = (context ? context.name : name)
96
- args = { limit: "" }
97
- items = item_cards(args.merge(context: context))
98
- extended_list = []
99
- already_extended = ::Set.new # avoid loops
100
-
101
- until items.empty?
102
- item = items.shift
103
- next if already_extended.include? item
104
- already_extended << item
105
- if item.collection?
106
- # keep items in order
107
- items.unshift(*item.item_cards)
108
- else # no further level of items
109
- extended_list << item
110
- end
111
- end
112
- extended_list
113
- end
114
-
115
- def extended_item_contents context=nil
116
- extended_item_cards(context).map(&:item_names).flatten
117
- end
118
-
119
- def extended_list context=nil
120
- context = (context ? context.name : name)
121
- args = { limit: "" }
122
- item_cards(args.merge(context: context)).map do |x|
123
- x.item_cards(args)
124
- end.flatten.map do |x|
125
- x.item_cards(args)
126
- end.flatten.map do |y|
127
- y.item_names(args)
128
- end.flatten
129
- # this could go on and on. more elegant to recurse until you don't have
130
- # a collection
131
- end
132
-
133
41
  def context_card
134
42
  @context_card || self
135
43
  end
@@ -137,9 +45,9 @@ end
137
45
  def with_context card
138
46
  old_context = @context_card
139
47
  @context_card = card if card
140
- result = yield
48
+ yield
49
+ ensure
141
50
  @context_card = old_context
142
- result
143
51
  end
144
52
 
145
53
  def contextual_content context_card, format_args={}, view_args={}
@@ -149,150 +57,11 @@ def contextual_content context_card, format_args={}, view_args={}
149
57
  end
150
58
  end
151
59
 
152
- def each_chunk opts={}
153
- content = opts[:content] || self.content
154
- chunk_type = opts[:chunk_type] || Card::Content::Chunk
155
- Card::Content.new(content, self).find_chunks(chunk_type).each do |chunk|
156
- next unless chunk.referee_name # filter commented nests
157
- yield chunk
158
- end
159
- end
160
-
161
- def each_reference_chunk content=nil
162
- reference_chunk_type = Card::Content::Chunk::Reference
163
- each_chunk content: content, chunk_type: reference_chunk_type do |chunk|
164
- yield chunk
165
- end
166
- end
167
-
168
- def each_nested_chunk content=nil
169
- nest_chunk_type = Card::Content::Chunk::Nest
170
- each_chunk content: content, chunk_type: nest_chunk_type do |chunk|
171
- yield chunk
172
- end
173
- end
174
-
175
- def each_item_name_with_options content=nil
176
- each_reference_chunk content do |chunk|
177
- options = chunk.respond_to?(:options) ? chunk.options : {}
178
- yield chunk.referee_name, options
179
- end
180
- end
181
-
182
- format do
183
- def item_links _args={}
184
- raw(render_core).split(/[,\n]/)
185
- end
186
-
187
- def nest_item cardish, options={}, &block
188
- options = item_view_options options
189
- options[:nest_name] = Card::Name[cardish].s
190
- nest cardish, options, &block
191
- end
192
-
193
- def implicit_item_view
194
- view = params[:item] || voo_items_view || default_item_view
195
- Card::View.canonicalize view
196
- end
197
-
198
- def voo_items_view
199
- return unless voo && (items = voo.items)
200
- items[:view]
201
- end
202
-
203
- def default_item_view
204
- :name
205
- end
206
-
207
- def item_view_options new_options={}
208
- options = (voo.items || {}).clone
209
- options = options.merge new_options
210
- options[:view] ||= implicit_item_view
211
- determine_item_view_options_type options
212
- options
213
- end
214
-
215
- def determine_item_view_options_type options
216
- return if options[:type]
217
- type_from_rule = card.item_type
218
- options[:type] = type_from_rule if type_from_rule
219
- end
220
-
221
- def nested_fields content=nil
222
- result = []
223
- each_nested_field(content) do |chunk|
224
- result << [chunk.referee_name, chunk.options]
225
- end
226
- result
227
- end
228
-
229
- def nested_fields_for_edit
230
- return normalized_edit_fields if edit_fields.present?
231
- result = []
232
- each_nested_field do |chunk|
233
- result << [chunk.options[:nest_name], chunk.options]
234
- end
235
- result
236
- end
237
-
238
- def edit_fields
239
- voo.edit_structure || []
240
- end
241
-
242
- def normalized_edit_fields
243
- edit_fields.map do |name_or_card, options|
244
- next [name_or_card, options || {}] if name_or_card.is_a?(Card)
245
- options ||= Card.fetch_name name_or_card
246
- options = { title: options } if options.is_a?(String)
247
- [card.name.field(name_or_card), options]
248
- end
249
- end
250
-
251
- def process_field chunk, processed, &_block
252
- return unless process_unique_field? chunk, processed
253
- yield chunk
254
- end
255
-
256
- def each_nested_field content=nil, &block
257
- processed = ::Set.new [card.key]
258
- content ||= _render_raw
259
- card.each_nested_chunk content do |chunk|
260
- next unless chunk.referee_name.to_name.field_of? card.name
261
- process_nested_chunk chunk, processed, &block
262
- end
263
- end
264
-
265
- def process_nested_chunk chunk, processed, &block
266
- virtual = chunk.referee_card && chunk.referee_card.virtual?
267
- # TODO: handle structures that are non-virtual
268
- method = virtual ? :process_virtual_field : :process_field
269
- send method, chunk, processed, &block
270
- end
271
-
272
- def process_virtual_field chunk, processed, &block
273
- return unless process_unique_field? chunk, processed
274
- subformat(chunk.referee_card).each_nested_field do |sub_chunk|
275
- process_field sub_chunk, processed, &block
276
- end
277
- end
278
-
279
- def process_unique_field? chunk, processed
280
- key = chunk.referee_name.key
281
- return false if processed.include? key
282
- processed << key
283
- true
284
- end
285
- end
286
-
287
60
  format :html do
288
61
  view :count do |args|
289
62
  card.item_names(args).size
290
63
  end
291
64
 
292
- view :tabs do
293
- construct_tabs "tabs"
294
- end
295
-
296
65
  view :carousel do
297
66
  bs_carousel unique_id, 0 do
298
67
  nest_item_array.each do |rendered_item|
@@ -300,122 +69,4 @@ format :html do
300
69
  end
301
70
  end
302
71
  end
303
-
304
- def construct_tabs tab_type
305
- tabs = { active: {}, paths: {} }
306
- voo.items[:view] ||= :content
307
- card.each_item_name_with_options(_render_raw) do |name, options|
308
- construct_tab tabs, name, options
309
- end
310
- lazy_loading_tabs tabs[:paths], tabs[:active][:name],
311
- tabs[:active][:content], type: tab_type
312
- end
313
-
314
- def construct_tab tabs, name, explicit_options
315
- tab_options = item_view_options explicit_options
316
- tabs[:paths][name] = {
317
- title: nest(name, view: :title, title: tab_options[:title]),
318
- path: nest_path(name, tab_options).html_safe }
319
- return unless tabs[:active].empty?
320
- tabs[:active] = { name: name, content: nest(name, tab_options) }
321
- end
322
-
323
- #def tab_title title, name
324
- # return name unless title
325
- # name.to_name.title title, @context_names
326
- #end
327
-
328
- # create a path for a nest with respect ot the nest options
329
- def nest_path name, nest_opts={}
330
- path_opts = { slot: nest_opts.clone }
331
- path_opts[:view] = path_opts[:slot].delete :view
332
- page_path name, path_opts
333
- end
334
-
335
- view :pills do
336
- construct_tabs "pills"
337
- end
338
-
339
- view :tabs_static do
340
- construct_static_tabs "tabs"
341
- end
342
-
343
- view :pills_static do
344
- construct_static_tabs "pills"
345
- end
346
-
347
- def construct_static_tabs tab_type
348
- tabs = {}
349
- card.item_cards.each do |item|
350
- tabs[item.name] = nest item, item_view_options(args)
351
- end
352
- static_tabs tabs, tab_type
353
- end
354
- end
355
-
356
- format :csv do
357
- view :core do
358
- if (item_view_options[:view] == :name_with_fields) && focal?
359
- title_row("item name") + name_with_field_rows
360
- else
361
- super()
362
- end
363
- end
364
-
365
- def name_with_field_rows
366
- return [] unless row_card_names.present?
367
-
368
- row_card_names.map do |item_name|
369
- CSV.generate_line row_from_field_names(item_name, columns)
370
- end.join
371
- end
372
-
373
- def row_card_names
374
- @row_cards ||= card.item_names
375
- end
376
-
377
- def columns
378
- columns = []
379
- csv_structure_card.format.each_nested_field do |chunk|
380
- columns << chunk.referee_name.tag
381
- end
382
- columns
383
- end
384
-
385
- def csv_structure_card
386
- card.rule_card(:csv_structure) || Card.fetch(row_card_names.first)
387
- end
388
-
389
- def row_from_field_names parent_name, field_names, view=:core
390
- field_names.each_with_object([parent_name]) do |field, row|
391
- row << nest([parent_name, field], view: view)
392
- end
393
- end
394
-
395
- def title_row extra_titles=nil
396
- titles = column_titles extra_titles
397
- return "" unless titles.present?
398
- CSV.generate_line titles.map { |title| title.to_s.upcase }
399
- rescue
400
- ""
401
- end
402
-
403
- def column_titles extra_titles=nil
404
- res = Array extra_titles
405
- card1 = Card.fetch card.item_names(limit: 1).first
406
- card1.each_nested_chunk do |chunk|
407
- res << column_title(chunk.options)
408
- end
409
- res.compact
410
- end
411
-
412
- def column_title opts
413
- if opts[:title]
414
- opts[:title]
415
- elsif %w[name link].member? opts[:view]
416
- opts[:view]
417
- else
418
- opts[:nest_name].to_name.tag
419
- end
420
- end
421
72
  end
@@ -1,6 +1,5 @@
1
1
  ::Card.error_codes[:conflict] = [:conflict, 409]
2
2
 
3
-
4
3
  def content= value
5
4
  self.db_content = value
6
5
  end
@@ -59,24 +58,44 @@ def last_draft_content
59
58
  end
60
59
 
61
60
  event :set_content, :store, on: :save do
62
- self.db_content = standard_content || "" # necessary?
63
- self.db_content = Card::Content.clean!(db_content) if clean_html?
61
+ self.db_content = prepare_content
64
62
  @selected_action_id = @selected_content = nil
65
63
  clear_drafts
66
64
  reset_patterns_if_rule true
67
65
  end
68
66
 
69
- event :save_draft, :store,
70
- on: :update, when: proc { Env.params["draft"] == "true" } do
67
+ event :save_draft, :store, on: :update, when: :draft? do
71
68
  save_content_draft content
72
69
  abort :success
73
70
  end
74
71
 
75
- event :set_default_content, :prepare_to_validate,
76
- on: :create, when: proc { |c| c.use_default_content? } do
72
+ event :set_default_content,
73
+ :prepare_to_validate,
74
+ on: :create, when: :use_default_content? do
77
75
  self.db_content = template.db_content
78
76
  end
79
77
 
78
+ def draft?
79
+ Env.params["draft"] == "true"
80
+ end
81
+
82
+ def prepare_content
83
+ cont = standard_content || "" # necessary?
84
+ clean_html? ? Card::Content.clean!(cont) : cont
85
+ end
86
+
80
87
  def use_default_content?
81
88
  !db_content_changed? && template && template.db_content.present?
82
89
  end
90
+
91
+ def unfilled?
92
+ blank_content? && blank_comment? && !subcards?
93
+ end
94
+
95
+ def blank_content?
96
+ content.blank? || content.strip.blank?
97
+ end
98
+
99
+ def blank_comment?
100
+ comment.blank? || comment.strip.blank?
101
+ end
@@ -0,0 +1,45 @@
1
+
2
+ def extended_item_cards context=nil
3
+ items = item_cards limit: "", context: (context || self).name
4
+ list = []
5
+ book = ::Set.new # avoid loops
6
+ extend_item_list items, list, book until items.empty?
7
+ list
8
+ end
9
+
10
+ def extended_item_contents context=nil
11
+ extended_item_cards(context).map(&:item_names).flatten
12
+ end
13
+
14
+ private
15
+
16
+ def extend_item_list items, list, book
17
+ item = items.shift
18
+ return if already_extended? item, book
19
+ if item.collection?
20
+ # keep items in order
21
+ items.unshift(*item.item_cards)
22
+ else # no further level of items
23
+ list << item
24
+ end
25
+ end
26
+
27
+ def already_extended? item, book
28
+ return true if book.include? item
29
+ book << item
30
+ false
31
+ end
32
+
33
+ # def extended_list context=nil
34
+ # context = (context ? context.name : name)
35
+ # args = { limit: "" }
36
+ # item_cards(args.merge(context: context)).map do |x|
37
+ # x.item_cards(args)
38
+ # end.flatten.map do |x|
39
+ # x.item_cards(args)
40
+ # end.flatten.map do |y|
41
+ # y.item_names(args)
42
+ # end.flatten
43
+ # # this could go on and on. more elegant to recurse until you don't have
44
+ # # a collection
45
+ # end