card 1.18.0 → 1.18.1

Sign up to get free protection for your applications and to get access to all the features.
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