card 1.18.0 → 1.18.1

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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/card.gemspec +20 -16
  4. data/db/migrate_core_cards/20150202143810_import_bootstrap_layout.rb +1 -1
  5. data/db/schema.rb +110 -92
  6. data/lib/card.rb +1 -0
  7. data/lib/card/content.rb +4 -73
  8. data/lib/card/content/chunk.rb +119 -0
  9. data/lib/card/content/parser.rb +75 -0
  10. data/lib/card/diff.rb +25 -398
  11. data/lib/card/diff/lcs.rb +247 -0
  12. data/lib/card/diff/result.rb +131 -0
  13. data/lib/card/director_register.rb +5 -0
  14. data/lib/card/query/attributes.rb +19 -13
  15. data/lib/card/set/event.rb +2 -1
  16. data/lib/card/set_pattern.rb +4 -2
  17. data/lib/card/spec_helper.rb +7 -1
  18. data/lib/card/stage_director.rb +33 -5
  19. data/lib/card/subcards.rb +11 -3
  20. data/lib/card/subdirector_array.rb +14 -1
  21. data/lib/cardio.rb +8 -5
  22. data/mod/01_core/chunk/include.rb +2 -2
  23. data/mod/01_core/chunk/link.rb +3 -3
  24. data/mod/01_core/chunk/literal.rb +20 -14
  25. data/mod/01_core/chunk/query_reference.rb +2 -2
  26. data/mod/01_core/chunk/reference.rb +47 -38
  27. data/mod/01_core/chunk/uri.rb +17 -13
  28. data/mod/01_core/format/html_format.rb +0 -2
  29. data/mod/01_core/set/all/actify.rb +12 -1
  30. data/mod/01_core/set/all/collection.rb +4 -4
  31. data/mod/01_core/set/all/fetch.rb +0 -27
  32. data/mod/01_core/set/all/name.rb +33 -12
  33. data/mod/01_core/set/all/pattern.rb +2 -6
  34. data/mod/01_core/set/all/phases.rb +0 -1
  35. data/mod/01_core/set/all/references.rb +2 -2
  36. data/mod/01_core/set/all/rules.rb +10 -3
  37. data/mod/01_core/set/all/tracked_attributes.rb +0 -1
  38. data/mod/01_core/set/all/type.rb +0 -14
  39. data/mod/01_core/spec/chunk/literal_spec.rb +1 -1
  40. data/mod/01_core/spec/chunk/uri_spec.rb +204 -201
  41. data/mod/01_core/spec/set/all/type_spec.rb +3 -1
  42. data/mod/01_history/lib/card/action.rb +7 -9
  43. data/mod/01_history/set/all/history.rb +6 -1
  44. data/mod/02_basic_types/set/all/all_csv.rb +1 -1
  45. data/mod/02_basic_types/set/type/pointer.rb +20 -9
  46. data/mod/03_machines/lib/javascript/wagn.js.coffee +1 -1
  47. data/mod/04_settings/set/right/structure.rb +7 -1
  48. data/mod/05_email/set/right/follow.rb +22 -22
  49. data/mod/05_email/set/type_plus_right/user/follow.rb +25 -26
  50. data/mod/05_standard/set/all/rich_html/wrapper.rb +12 -6
  51. data/mod/05_standard/set/rstar/rules_editor.rb +6 -4
  52. data/mod/05_standard/set/self/all.rb +0 -10
  53. data/mod/05_standard/set/self/stats.rb +6 -15
  54. data/mod/05_standard/set/type/set.rb +0 -6
  55. data/mod/05_standard/spec/chunk/include_spec.rb +2 -2
  56. data/mod/05_standard/spec/chunk/link_spec.rb +1 -1
  57. data/mod/05_standard/spec/chunk/query_reference_spec.rb +5 -4
  58. data/spec/lib/card/chunk_spec.rb +7 -5
  59. data/spec/lib/card/content_spec.rb +11 -11
  60. data/spec/lib/card/diff_spec.rb +4 -4
  61. data/spec/lib/card/stage_director_spec.rb +56 -0
  62. data/spec/lib/card/subcards_spec.rb +0 -1
  63. data/spec/models/card/type_transition_spec.rb +5 -42
  64. metadata +12 -23
  65. data/lib/card/chunk.rb +0 -122
@@ -31,11 +31,13 @@ describe Card::Set::All::Type do
31
31
  Card::Auth.as_bot do
32
32
  Card.create! name: 'Topic', type: 'Cardtype'
33
33
  Card.create! name: 'Topic+*type+*structure', content: '{{+results}}'
34
- Card.create! name: 'Topic+results+*type plus right+*structure', type: 'Search', content: '{}'
34
+ Card.create! name: 'Topic+results+*type plus right+*structure',
35
+ type: 'Search', content: '{}'
35
36
  end
36
37
  end
37
38
 
38
39
  it 'should clear cache of structured nested card after saving' do
40
+ pending 'need new mechanism to replace #reset_type_specific_fields'
39
41
  Card::Auth.as_bot do
40
42
  expect(Card.fetch('t1+results', new: {}).type_name).to eq('Basic')
41
43
 
@@ -150,11 +150,11 @@ class Card
150
150
  end
151
151
 
152
152
  def red?
153
- content_diff_builder.red?
153
+ content_diff_object.red?
154
154
  end
155
155
 
156
156
  def green?
157
- content_diff_builder.green?
157
+ content_diff_object.green?
158
158
  end
159
159
 
160
160
  # def diff
@@ -174,18 +174,16 @@ class Card
174
174
  def content_diff diff_type=:expanded, opts=nil
175
175
  return unless new_content?
176
176
  if diff_type == :summary
177
- content_diff_builder(opts).summary
177
+ content_diff_object(opts).summary
178
178
  else
179
- content_diff_builder(opts).complete
179
+ content_diff_object(opts).complete
180
180
  end
181
181
  end
182
182
 
183
- def content_diff_builder opts=nil
184
- @content_diff_builder ||= begin
183
+ def content_diff_object opts=nil
184
+ @diff ||= begin
185
185
  diff_args = opts || card.include_set_modules.diff_args
186
- Card::Diff::DiffBuilder.new(
187
- old_values[:content], new_values[:content], diff_args
188
- )
186
+ Card::Diff.new old_values[:content], new_values[:content], diff_args
189
187
  end
190
188
  end
191
189
 
@@ -53,7 +53,8 @@ end
53
53
 
54
54
  event :finalize_act,
55
55
  after: :finalize_action,
56
- when: proc { |c| !c.supercard } do
56
+ when: proc { |c| c.act_card? } do
57
+ # removed subcards can leave behind actions without card id
57
58
  if @current_act.actions(true).empty?
58
59
  @current_act.delete
59
60
  @current_act = nil
@@ -62,6 +63,10 @@ event :finalize_act,
62
63
  end
63
64
  end
64
65
 
66
+ def act_card?
67
+ self == DirectorRegister.act_card
68
+ end
69
+
65
70
  event :rollback_actions, :prepare_to_validate,
66
71
  on: :update,
67
72
  when: proc { |c| c.rollback_request? } do
@@ -32,7 +32,7 @@ format :csv do
32
32
  ''
33
33
  else
34
34
  titles = parsed_content.map do |chunk|
35
- next if chunk.class != Card::Chunk::Include
35
+ next if chunk.class != Card::Content::Chunk::Include
36
36
  opts = chunk.options
37
37
  if %w(name link).member? opts[:view]
38
38
  opts[:view]
@@ -1,5 +1,4 @@
1
1
 
2
-
3
2
  event :add_and_drop_items, :prepare_to_validate, on: :save do
4
3
  adds = Env.params['add_item']
5
4
  drops = Env.params['drop_item']
@@ -129,7 +128,8 @@ format :html do
129
128
  view :checkbox do |_args|
130
129
  options = card.option_names.map do |option_name|
131
130
  checked = card.item_names.include?(option_name)
132
- label = ((o_card = Card.fetch(option_name)) && o_card.label) || option_name
131
+ o_card = Card.fetch option_name
132
+ label = (o_card && o_card.label) || option_name
133
133
  id = "pointer-checkbox-#{option_name.to_name.key}"
134
134
  description = pointer_option_description option_name
135
135
  <<-HTML
@@ -250,18 +250,29 @@ def diff_args
250
250
  { format: :pointer }
251
251
  end
252
252
 
253
+
253
254
  def item_cards args={}
254
255
  if args[:complete]
255
- query = { referred_to_by: name }.merge args
256
+ query = args.reverse_merge referred_to_by: name
256
257
  Card::Query.run query
258
+ elsif args[:known_only]
259
+ known_item_cards args
257
260
  else
261
+ fetch_or_initialize_item_cards args
262
+ end
263
+ end
258
264
 
259
- itype = args[:type] || item_type
260
- # warn "item_card[#{inspect}], :complete"
261
- item_names(args).map do |name|
262
- new_args = itype ? { type: itype } : {}
263
- Card.fetch name, new: new_args
264
- end.compact # compact? can't be nil, right?
265
+ def known_item_cards args={}
266
+ item_names(args).map do |name|
267
+ Card.fetch name
268
+ end.compact
269
+ end
270
+
271
+ def fetch_or_initialize_item_cards args
272
+ itype = args[:type] || item_type
273
+ new_args = itype ? { type: itype } : {}
274
+ item_names(args).map do |name|
275
+ Card.fetch name, new: new_args
265
276
  end
266
277
  end
267
278
 
@@ -232,7 +232,7 @@ $(window).ready ->
232
232
  $(this).closest('form').submit()
233
233
 
234
234
  $('body').on 'click', '.renamer-updater', ->
235
- $(this).closest('form').find('#card_update_referencers').val 'true'
235
+ $(this).closest('form').find('#card_update_referers').val 'true'
236
236
 
237
237
  $('body').on 'submit', '.edit_name-view .card-form', ->
238
238
  confirmer = $(this).find '.alert'
@@ -17,6 +17,12 @@ event :update_structurees_references, :integrate,
17
17
  end
18
18
  end
19
19
 
20
+ event :reset_cache_to_use_new_structure,
21
+ before: :update_structurees_references do
22
+ Card::Cache.reset_hard
23
+ Card::Cache.reset_soft
24
+ end
25
+
20
26
  event :update_structurees_type, :finalize,
21
27
  changed: :type_id, when: proc { |c| c.assigns_type? } do
22
28
  update_structurees type_id: type_id
@@ -25,7 +31,7 @@ end
25
31
  def structuree_names
26
32
  if (wql = structuree_statement)
27
33
  Auth.as_bot do
28
- Card::Query.run(wql.merge return: :name)
34
+ Card::Query.run wql.merge(return: :name)
29
35
  end
30
36
  else
31
37
  []
@@ -8,7 +8,7 @@ def options_rule_card
8
8
  Card.new(
9
9
  name: 'follow_options_card',
10
10
  type_code: :pointer,
11
- content: option_cards.map { |oc| "[[#{oc.title}]]" }.join("\n")
11
+ content: option_cards.map { |oc| "[[#{oc.name}]]" }.join("\n")
12
12
  )
13
13
  end
14
14
 
@@ -54,29 +54,29 @@ format :html do
54
54
  end
55
55
 
56
56
  view :follow_status do |args|
57
- %(
58
- <h4>Get notified about changes</h4>
57
+ delete_options =
58
+ wrap_with(:ul, class: 'delete-list list-group') do
59
+ card.item_names.map do |option|
60
+ content_tag :li, class: 'list-group-item' do
61
+ condition = option == '*never' ? '*always' : option
62
+ subformat(card).render_follow_item condition: condition
63
+ end
64
+ end.join "\n"
65
+ end
66
+
67
+ follow_link =
68
+ card_link args[:card_key],
69
+ text: 'more options',
70
+ path_opts: {
71
+ view: :related,
72
+ related: { name: card.name, view: :edit_single_rule }
73
+ },
74
+ class: 'btn update-follow-link',
75
+ 'data-card_key' => args[:card_key]
59
76
 
60
- #{wrap_with(:ul, class: 'delete-list list-group') do
61
- card.item_names.map do |option|
62
- content_tag :li, class: 'list-group-item' do
63
- condition = option == '*never' ? '*always' : option
64
- subformat(card).render_follow_item condition: condition
65
- end
66
- end.join "\n"
67
- end}
77
+ header = '<h4>Get notified about changes</h4>'
68
78
 
69
- #{card_link(args[:card_key], text: 'more options',
70
- path_opts: {
71
- view: :related,
72
- related: {
73
- name: card.name,
74
- view: :related_edit_rule
75
- }
76
- },
77
- class: 'btn update-follow-link',
78
- 'data-card_key' => args[:card_key])}
79
- )
79
+ [header, delete_options, follow_link].join "\n\n"
80
80
  end
81
81
 
82
82
  view :delete_follow_rule_button do |_args|
@@ -1,16 +1,19 @@
1
1
  include Card::Set::Type::Pointer
2
2
 
3
3
  def raw_content
4
- @raw_content ||=
5
- if left
6
- items = if left.type_id == Card::UserID
7
- user = left
8
- follow_rules = Card.preference_cards left.name, 'follow'
9
- follow_rules.map { |card| "[[#{card.name}]]" }
10
- end.join "\n"
11
- else
12
- ''
13
- end
4
+ item_names.map { |name| "[[#{name}]]" }
5
+ end
6
+
7
+ def item_names
8
+ if (user = left)
9
+ Card.preference_names user.name, 'follow'
10
+ else
11
+ []
12
+ end
13
+ end
14
+
15
+ def item_cards
16
+ item_names.map { |name| Card.fetch name }
14
17
  end
15
18
 
16
19
  def virtual?
@@ -61,28 +64,24 @@ format :html do
61
64
  end
62
65
 
63
66
  def each_suggestion
64
- if (suggestions = Card['follow suggestions'])
65
- suggestions.item_names.each do |sug|
66
- if (set_card = Card.fetch sug.to_name.left) &&
67
- set_card.type_code == :set
68
- option_card = Card.fetch(sug.to_name.right) ||
69
- Card[sug.to_name.right.to_sym]
70
- option = if option_card.follow_option?
71
- option_card.name
72
- else
73
- '*always'
74
- end
75
- yield(set_card, option)
76
- elsif (set_card = Card.fetch sug) && set_card.type_code == :set
77
- yield(set_card, '*always')
78
- end
67
+ return unless (suggestions = Card['follow suggestions'])
68
+ suggestions.item_names.each do |sug|
69
+ set_card = Card.fetch sug.to_name.left
70
+ if set_card && set_card.type_code == :set
71
+ sugtag = sug.to_name.right
72
+ option_card = Card.fetch(sugtag) || Card[sugtag.to_sym]
73
+ option = option_card.follow_option? ? option_card.name : '*always'
74
+ yield(set_card, option)
75
+ elsif (set_card = Card.fetch sug) && set_card.type_code == :set
76
+ yield(set_card, '*always')
79
77
  end
80
78
  end
81
79
  end
82
80
 
83
81
  # returns hashes with existing and suggested follow options
84
82
  # structure:
85
- # set_pattern_class => [ {card: rule_card, options: ['*always', '*created'] },.... ]
83
+ # set_pattern_class =>
84
+ # [ {card: rule_card, options: ['*always', '*created'] },.... ]
86
85
  def followed_by_set
87
86
  res = Hash.new { |h, k| h[k] = [] }
88
87
  never = Card[:never].name
@@ -1,6 +1,6 @@
1
1
  format :html do
2
2
  def slot_options args
3
- @@slot_option_keys ||= Card::Chunk::Include.options.reject { |k| k == :view }.unshift :home_view
3
+ @@slot_option_keys ||= Card::Content::Chunk::Include.options.reject { |k| k == :view }.unshift :home_view
4
4
  options_hash = {}
5
5
 
6
6
  if @context_names.present?
@@ -112,11 +112,17 @@ format :html do
112
112
  css_class = "alert alert-#{alert_type} "
113
113
  css_class += 'alert-dismissible ' if args[:dismissible]
114
114
  css_class += args[:alert_class] if args[:alert_class]
115
- close_button = args[:dismissible] ? %(
116
- <button type="button" class="close" data-dismiss="alert" aria-label="Close">
117
- <span aria-hidden="true">&times;</span>
118
- </button>
119
- ) : ''
115
+ close_button =
116
+ if args[:dismissible]
117
+ %(
118
+ <button type="button" class="close" data-dismiss="alert"
119
+ aria-label="Close">
120
+ <span aria-hidden="true">&times;</span>
121
+ </button>
122
+ )
123
+ else
124
+ ''
125
+ end
120
126
  content_tag :div, class: css_class, role: 'alert' do
121
127
  close_button + output(yield args)
122
128
  end
@@ -133,7 +133,9 @@ format :html do
133
133
  end
134
134
  end
135
135
 
136
- view :related_edit_rule, view: :edit_rule
136
+ view :edit_single_rule do |args|
137
+ %(<div class="edit-single-rule panel-body">#{render_edit_rule args}</div>)
138
+ end
137
139
 
138
140
  def default_edit_rule_args args
139
141
  args[:remote] ||= true
@@ -162,7 +164,7 @@ format :html do
162
164
  end
163
165
  end
164
166
 
165
- def default_related_edit_rule_args args
167
+ def default_edit_single_rule_args args
166
168
  args[:remote] ||= false
167
169
  args[:success] ||= {
168
170
  card: args[:parent] || card,
@@ -172,10 +174,10 @@ format :html do
172
174
  item: nil
173
175
  }
174
176
  default_edit_rule_args args
175
- related_edit_rule_button_args args
177
+ edit_single_rule_button_args args
176
178
  end
177
179
 
178
- def related_edit_rule_button_args args
180
+ def edit_single_rule_button_args args
179
181
  args[:delete_button] = delete_button args, '.card-slot.related-view'
180
182
  args[:cancel_button] = card_link(
181
183
  args[:success][:id],
@@ -8,7 +8,6 @@ event :admin_tasks, :initialize, on: :update do
8
8
  when :empty_trash then Card.empty_trash
9
9
  when :clear_view_cache then Card::ViewCache.reset
10
10
  when :delete_old_revisions then Card::Action.delete_old
11
- when :delete_old_sessions then Card.delete_old_sessions
12
11
  when :repair_permissions then Card.repair_all_permissions
13
12
  end
14
13
  Env.params[:success] = Card[:stats].name
@@ -18,12 +17,3 @@ event :admin_tasks, :initialize, on: :update do
18
17
  end
19
18
  end
20
19
  end
21
-
22
- module ClassMethods
23
- def delete_old_sessions
24
- return unless (months = Env.params[:months].to_i) && months > 0
25
- ActiveRecord::SessionStore::Session.delete_all(
26
- ['updated_at < ?', months.months.ago]
27
- )
28
- end
29
- end
@@ -29,26 +29,17 @@ format :html do
29
29
  <td>#{Card::Reference.count}</td>
30
30
  <td>#{link_to 'repair all', card_path('update/:all?task=repair_references')}</td>
31
31
  </tr>
32
- <tr>
33
- <td>sessions</td>
34
- <td>#{ActiveRecord::SessionStore::Session.count}</td>
35
- <td>
36
- delete older than
37
- #{delete_sessions_link 1}
38
- #{delete_sessions_link 2}
39
- #{delete_sessions_link 3}
40
- months
41
- </td>
42
- </tr>
43
- #{if Card.config.view_cache
44
- %(
32
+ #{
33
+ if Card.config.view_cache
34
+ %{
45
35
  <tr>
46
36
  <td>view cache</td>
47
37
  <td>#{Card::ViewCache.count}</td>
48
38
  <td>#{link_to 'clear view cache', card_path('update/:all?task=clear_view_cache')}</td>
49
39
  </tr>
50
- )
51
- end}
40
+ }
41
+ end
42
+ }
52
43
 
53
44
  <tr>
54
45
  <td>memory now</td>
@@ -228,12 +228,6 @@ def junction_only?
228
228
  end
229
229
  end
230
230
 
231
- def reset_set_patterns
232
- Card.cached_set_members(key).each do |mem|
233
- Card.expire mem
234
- end
235
- end
236
-
237
231
  def label
238
232
  if (klass = subclass_for_set)
239
233
  klass.label cardname.left
@@ -1,9 +1,9 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
- describe Card::Chunk::Include, 'Inclusion' do
3
+ describe Card::Content::Chunk::Include, 'Inclusion' do
4
4
  context 'syntax parsing' do
5
5
  before do
6
- @class = Card::Chunk::Include
6
+ @class = Card::Content::Chunk::Include
7
7
  end
8
8
 
9
9
  let :instance do