card 1.92 → 1.92.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 47455178df73a19b8c9a200fb6ffc996f5303489
4
- data.tar.gz: fb7046e99420ee3cc2af2dc47723a1d3ad17ad73
3
+ metadata.gz: f28f43edfef2752d5cfefbfed009278c4852af46
4
+ data.tar.gz: 4f94927063af307286622bf14c9c21738720c3fd
5
5
  SHA512:
6
- metadata.gz: 8d6a3bdc814d7f8ca80b0a5c08f0e0b6f9cff85ebd35737c09104bc3a6c5b35779b71ed982d692f05a2d1955ea6d5cd355fba17a12915f878ffbb55f68377451
7
- data.tar.gz: 7d962a151eeebaa50d17df1b7e25883209a62744395669190f78ac02afc627cca3da72646d7f53b63f7b13785fa81279d7de1edafc44e4119c0b4ecb52aa0847
6
+ metadata.gz: 685d0d0cf2e26a2237ac3d0869321e5dcfa403fd7063599e6b458fa971e7279cf05b40c91370ef4c34717fa41a7f1256f7cb5f93cdf70a286a3e82d3363aa4b1
7
+ data.tar.gz: 211059237c2230c26de7e3e2e53bf06d68af128d7b7dd66efd3cacb926510fcd1cddf9da70e34d094eec4fa253bf5b112a341dd0b926bb50d24bbef7d4a42b82
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2
1
+ 0.2.1
@@ -1,33 +1,81 @@
1
1
  module Patches
2
2
  module ActiveJob
3
- # monkeypatch ActiveJob so that it can handle more types of arguments
3
+ # Monkeypatch ActiveJob so that it can handle more types of arguments.
4
+ # Add Integer hash keys and Symbol, Time, DateTime hash values and
5
+ # ActionController::Parameters
4
6
  module Arguments
5
7
  CLASS_NAME_KEY = "_aj_class_name_key".freeze
8
+ VALUE_KEY = "_aj_value_key".freeze
9
+ INTEGER_KEYS_KEY = "_aj_integer_keys".freeze
6
10
 
7
11
  private
8
12
 
9
13
  def serialize_argument argument
10
14
  case argument
11
15
  when Symbol, Time, DateTime
12
- { value: argument.to_s, CLASS_NAME_KEY => argument.class.to_s }
16
+ { VALUE_KEY => argument.to_s, CLASS_NAME_KEY => argument.class.to_s }
13
17
  when ActionController::Parameters
14
- { value: serialize_argument(argument.to_unsafe_h),
15
- CLASS_NAME_KEY: argument.class.to_s }
18
+ { VALUE_KEY => serialize_argument(argument.to_unsafe_h),
19
+ CLASS_NAME_KEY => argument.class.to_s }
20
+ when Hash
21
+ integer_keys = argument.each_key.grep(Integer).map(&:to_s)
22
+ result = super
23
+ result[INTEGER_KEYS_KEY] = integer_keys
24
+ result
16
25
  else
17
26
  super
18
27
  end
19
28
  end
20
29
 
21
- def deserialize_argument argument
22
- return super unless argument.is_a?(Hash) &&
23
- argument[CLASS_NAME_KEY]
24
- case argument[CLASS_NAME_KEY]
30
+ def serialize_hash_key key
31
+ case key
32
+ when Integer
33
+ key.to_s
34
+ else
35
+ super
36
+ end
37
+ end
38
+
39
+ # all custom serialized arguments become hashes
40
+ # hence for deserializing we only have to check hashes
41
+ def deserialize_hash serialized_hash
42
+ if serialized_hash[CLASS_NAME_KEY]
43
+ deserialize_object serialized_hash
44
+ else
45
+ handle_integer_keys super
46
+ end
47
+ end
48
+
49
+ def handle_integer_keys result
50
+ if (integer_keys = result.delete(INTEGER_KEYS_KEY) && integer_keys.present?)
51
+ result = transform_integer_keys(result, integer_keys)
52
+ end
53
+ result
54
+ end
55
+
56
+ def deserialize_object hash
57
+ value = hash[VALUE_KEY]
58
+ class_name = hash[CLASS_NAME_KEY]
59
+ case class_name
25
60
  when "Symbol"
26
- argument[:value].to_sym
61
+ value.to_sym
27
62
  when "Time", "DateTime"
28
- Object.const_get(argument[CLASS_NAME_KEY]).parse argument[:value]
63
+ Object.const_get(class_name).parse value
64
+ when "ActionController::Parameters"
65
+ # TODO: handle the permitted status
66
+ ActionController::Parameters.new deserialize_hash(value)
29
67
  else
30
- argument[:value]
68
+ value
69
+ end
70
+ end
71
+
72
+ def transform_integer_keys(hash, integer_keys)
73
+ hash.transform_keys do |key|
74
+ if integer_keys.include?(key)
75
+ key.to_i
76
+ else
77
+ key
78
+ end
31
79
  end
32
80
  end
33
81
  end
@@ -133,7 +133,7 @@ class Card
133
133
 
134
134
  def to_s level=1
135
135
  str = @card.name.to_s.clone
136
- if @subdirectors
136
+ if @subdirectors.present?
137
137
  subs = subdirectors.map { |d| " " * level + d.to_s(level + 1) }.join "\n"
138
138
  str << "\n#{subs}"
139
139
  end
@@ -27,6 +27,7 @@ class Card
27
27
  rescue => e # don't rollback
28
28
  Card::Error.current = e
29
29
  warn "exception in integrate stage: #{e.message}"
30
+ warn e.backtrace.join "\n"
30
31
  @card.notable_exception_raised
31
32
  return false
32
33
  ensure
@@ -44,7 +44,7 @@ class Card
44
44
  extend Card::Cache::Prepopulate
45
45
 
46
46
  @prepopulating = %w(test cucumber).include? Rails.env
47
- @no_rails_cache = %w(test cucumber).include?(Rails.env) ||
47
+ @no_rails_cache = %w(test).include?(Rails.env) ||
48
48
  ENV["NO_RAILS_CACHE"]
49
49
  @@cache_by_class = {}
50
50
  cattr_reader :cache_by_class
@@ -87,7 +87,7 @@ class Card
87
87
  def prepare_stub_nest stub_hash
88
88
  stub_card = Card.fetch_from_cast stub_hash[:cast]
89
89
  stub_options = stub_hash[:options]
90
- if stub_card.key.present? && stub_card.key == card.key
90
+ if stub_card&.key.present? && stub_card.key == card.key
91
91
  stub_options[:nest_name] ||= "_self"
92
92
  end
93
93
  yield stub_card, stub_hash[:mode], stub_options, stub_hash[:override]
@@ -1,14 +1,13 @@
1
- require_relative "load_strategy/eval"
2
- require_relative "load_strategy/pattern_tmp_files"
3
- require_relative "load_strategy/set_binding_magic"
4
- require_relative "load_strategy/set_tmp_files"
5
- require_relative "load_strategy/tmp_files"
6
-
7
1
  class Card
8
2
  module Mod
3
+ require_dependency "card/mod/load_strategy/eval"
4
+ require_dependency "card/mod/load_strategy/pattern_tmp_files"
5
+ require_dependency "card/mod/load_strategy/set_binding_magic"
6
+ require_dependency "card/mod/load_strategy/set_tmp_files"
7
+ require_dependency "card/mod/load_strategy/tmp_files"
8
+
9
9
  # Shared code for the three different load strategies: Eval, TmpFiles and BindingMagic
10
10
  class LoadStrategy
11
-
12
11
  def self.klass symbol
13
12
  case symbol
14
13
  when :tmp_files then TmpFiles
@@ -104,12 +104,12 @@ event :set_default_status, :prepare_to_validate, on: :create do
104
104
  add_subfield :status, content: default_status
105
105
  end
106
106
 
107
- def confirm_ok?
107
+ def can_approve?
108
108
  Card.new(type_id: Card.default_accounted_type_id).ok? :create
109
109
  end
110
110
 
111
111
  event :generate_confirmation_token,
112
- :prepare_to_store, on: :create, when: :confirm_ok? do
112
+ :prepare_to_store, on: :create, when: :can_approve? do
113
113
  add_subfield :token, content: generate_token
114
114
  end
115
115
 
@@ -2,7 +2,7 @@ format :html do
2
2
  def invitation?
3
3
  return @invitation unless @invitation.nil?
4
4
  @invitation = Auth.signed_in? &&
5
- (card.fetch trait: :account, new: {}).confirm_ok?
5
+ (card.fetch trait: :account, new: {}).can_approve?
6
6
  # consider making account a card_accessor?
7
7
  end
8
8
 
@@ -87,13 +87,13 @@ format :html do
87
87
  end
88
88
 
89
89
  def approve_with_token_link account, token_action
90
- return unless account.confirm_ok?
90
+ return unless account.can_approve?
91
91
  link_to_card card, "#{token_action} verification email",
92
92
  path: { action: :update, approve_with_token: true }
93
93
  end
94
94
 
95
95
  def approve_without_token_link account
96
- return unless account.confirm_ok?
96
+ return unless account.can_approve?
97
97
  link_to_card card, "Approve without verification",
98
98
  path: { action: :update, approve_without_token: true }
99
99
  end
@@ -139,7 +139,7 @@ end
139
139
  event :approve_with_token, :validate,
140
140
  on: :update,
141
141
  when: proc { Env.params[:approve_with_token] } do
142
- abort :failure, "illegal approval" unless account.confirm_ok?
142
+ abort :failure, "illegal approval" unless account.can_approve?
143
143
  account.reset_token
144
144
  account.send_account_verification_email
145
145
  end
@@ -147,7 +147,7 @@ end
147
147
  event :approve_without_token, :validate,
148
148
  on: :update,
149
149
  when: proc { Env.params[:approve_without_token] } do
150
- abort :failure, "illegal approval" unless account.confirm_ok?
150
+ abort :failure, "illegal approval" unless account.can_approve?
151
151
  activate_account
152
152
  end
153
153
 
@@ -11,7 +11,7 @@ class Bootstrap
11
11
  @items = []
12
12
  instance_exec &block
13
13
 
14
- @html.div class: "carousel slide", id: id, data: { ride: "carousel" } do
14
+ @html.div class: "carousel slide", id: id, "data-ride" => "carousel" do
15
15
  indicators
16
16
  items
17
17
  control_prev
@@ -30,7 +30,7 @@ class Bootstrap
30
30
  add_class html_opts, "active" if index == @active_item_index
31
31
  @html.div html_opts do
32
32
  item = item.call if item.respond_to?(:call)
33
- @html.text!(item) if item.is_a?(String)
33
+ @html << item if item.is_a?(String)
34
34
  end
35
35
  end
36
36
  end
@@ -38,7 +38,7 @@ class Bootstrap
38
38
 
39
39
  def control_prev
40
40
  @html.a class: "carousel-control-prev", href: "##{@id}", role: "button",
41
- data: { slide: "prev" } do
41
+ "data-slide" => "prev" do
42
42
  @html.span class: "carousel-control-prev-icon", "aria-hidden" => "true"
43
43
  @html.span "Previous", class: "sr-only"
44
44
  end
@@ -46,7 +46,7 @@ class Bootstrap
46
46
 
47
47
  def control_next
48
48
  @html.a class: "carousel-control-next", href: "##{@id}", role: "button",
49
- data: { slide: "next" } do
49
+ "data-slide": "next" do
50
50
  @html.span class: "carousel-control-next-icon", "aria-hidden" => "true"
51
51
  @html.span "Next", class: "sr-only"
52
52
  end
@@ -40,7 +40,7 @@ class Bootstrap
40
40
  def input type, text: nil, label: nil, id: nil
41
41
  @html.input id: id, class: "form-control", type: type do
42
42
  @html.label label, for: id if label
43
- @html.text! text if text
43
+ @html << text if text
44
44
  end
45
45
  end
46
46
 
@@ -56,7 +56,7 @@ class Bootstrap
56
56
  define_method tag do |text: nil, id:, label: |
57
57
  @html.input id: id, class: "form-control", type: tag do
58
58
  @html.label label, for: id if label
59
- @html.text! text
59
+ @html << text
60
60
  end
61
61
  end
62
62
  end
@@ -62,4 +62,13 @@ describe Bootstrap::Component::Carousel do
62
62
  end
63
63
  end
64
64
  end
65
+
66
+ it "doesn't escape markup" do
67
+ carousel = subject.bs_carousel "csID", 0 do
68
+ item "<strong>item 2</strong>"
69
+ end
70
+ expect(carousel).to have_tag "div.carousel-item" do
71
+ with_tag :strong, text: "item 2"
72
+ end
73
+ end
65
74
  end
@@ -8,7 +8,6 @@ end
8
8
  event :upload_attachment, :prepare_to_validate,
9
9
  on: :save, when: proc { |c| c.preliminary_upload? } do
10
10
  save_original_filename # save original filename as comment in action
11
- # binding.pry
12
11
  write_identifier # set db_content
13
12
  # (needs original filename to determine extension)
14
13
  store_attachment!
@@ -107,11 +107,7 @@ format :html do
107
107
  <table role="presentation" class="table table-striped">
108
108
  <tbody class="files">
109
109
  <tr class="template-download fade show">
110
- <td>
111
- <span class="preview">
112
- #{preview}
113
- </span>
114
- </td>
110
+ <td><span class="preview">#{preview}</span></td>
115
111
  <td>
116
112
  <p class="name">
117
113
  #{card.original_filename}
@@ -53,8 +53,7 @@ class Card
53
53
  end
54
54
 
55
55
  def layout_from_card_or_code name
56
- layout_card = Card.fetch name.to_s, skip_virtual: true,
57
- skip_modules: true
56
+ layout_card = Card.quick_fetch name
58
57
  if layout_card && layout_card.ok?(:read)
59
58
  layout_card.content
60
59
  elsif (hardcoded_layout = LAYOUTS[name])
@@ -54,6 +54,7 @@ def view_cache_keys new_key=nil
54
54
  @view_cache_keys << new_key if new_key
55
55
  append_missing_view_cache_keys
56
56
  @view_cache_keys.uniq!
57
+ @view_cache_keys
57
58
  end
58
59
 
59
60
  def append_missing_view_cache_keys
@@ -63,15 +64,15 @@ def append_missing_view_cache_keys
63
64
  end
64
65
 
65
66
  def hard_write_view_cache_keys
66
- # puts "WRITE VIEW CACHE KEYS (#{name}): #{view_cache_keys}"
67
+ # puts "WRITE VIEW CACHE KEYS (#{name}): #{view_cache_keys}"
67
68
  return unless Card.cache.hard
68
- Card.cache.hard.write_attribute key, :view_cache_keys, @view_cache_keys
69
+ Card.cache.hard.write_attribute key, :view_cache_keys, view_cache_keys
69
70
  end
70
71
 
71
72
  def expire_views
72
- # puts "EXPIRE VIEW CACHE (#{name}): #{view_cache_keys}"
73
+ # puts "EXPIRE VIEW CACHE (#{name}): #{view_cache_keys}"
73
74
  return unless view_cache_keys.present?
74
- Array.wrap(@view_cache_keys).each do |view_cache_key|
75
+ Array.wrap(view_cache_keys).each do |view_cache_key|
75
76
  Card::View.cache.delete view_cache_key
76
77
  end
77
78
  @view_cache_keys = nil
@@ -294,9 +294,9 @@ format :html do
294
294
  end
295
295
 
296
296
  view :carousel do
297
- bs_carousel unique_id do
297
+ bs_carousel unique_id, 0 do
298
298
  nest_item_array.each do |rendered_item|
299
- item rendered_item
299
+ item(rendered_item)
300
300
  end
301
301
  end
302
302
  end
@@ -35,7 +35,7 @@ class Card
35
35
  row 10, 2 do
36
36
  column do
37
37
  html title
38
- tag(:span, "text-muted pl-1 badge") {summary}
38
+ tag(:span, "text-muted pl-1 badge") { summary }
39
39
  end
40
40
  column act_links, class: "text-right"
41
41
  end
@@ -93,7 +93,7 @@ class Card
93
93
  def count_types
94
94
  @count_types ||=
95
95
  approved_actions.each_with_object(
96
- Hash.new {|h, k| h[k] = 0}
96
+ Hash.new { |h, k| h[k] = 0 }
97
97
  ) do |action, type_cnt|
98
98
  type_cnt[action.action_type] += 1
99
99
  end
@@ -186,18 +186,19 @@ class Card
186
186
 
187
187
  def revert_link
188
188
  revert_actions_link "revert to this", revert_to: :this,
189
- slot_selector: ".card-slot.history-view"
189
+ slot_selector: ".card-slot.history-view"
190
190
  end
191
191
 
192
- def revert_actions_link link_text, revert_to: :this, slot_selector:
192
+ def revert_actions_link link_text, revert_to: :this, slot_selector: nil, html_args: {}
193
193
  return unless card.ok? :update
194
- args = { remote: true, method: :post, rel: "nofollow",
195
- path: { action: :update, view: :open, look_in_trash: true,
196
- revert_actions: @act.actions.map(&:id),
197
- "data-slot-selector" => slot_selector } }
198
- add_class args, "slotter"
199
- args[:path][:revert_to] = revert_to
200
- link_to link_text, args
194
+ html_args.merge! remote: true, method: :post, rel: "nofollow",
195
+ path: { action: :update, view: :open, look_in_trash: true,
196
+ revert_actions: @act.actions.map(&:id),
197
+ revert_to: revert_to }
198
+
199
+ html_args[:path]["data-slot-selector"] = slot_selector if slot_selector
200
+ add_class html_args, "slotter"
201
+ link_to link_text, html_args
201
202
  end
202
203
 
203
204
  def deletion_act?
@@ -30,7 +30,7 @@ event :finalize_action, :finalize, when: :finalize_action? do
30
30
  @current_action.update_attributes! card_id: id
31
31
 
32
32
  # Note: #last_change_on uses the id to sort by date
33
- # so the changes for the create changes have to be created befire the first change
33
+ # so the changes for the create changes have to be created before the first change
34
34
  store_card_changes_for_create_action if first_change?
35
35
  store_card_changes if @current_action.action_type != :create
36
36
  elsif @current_action.card_changes.reload.empty?
@@ -77,15 +77,19 @@ end
77
77
  event :finalize_act,
78
78
  after: :finalize_action,
79
79
  when: proc { |c| c.act_card? } do
80
- # removed subcards can leave behind actions without card id
81
- if @current_act.actions.reload.empty?
82
- @current_act.delete
83
- @current_act = nil
84
- else
85
- @current_act.update_attributes! card_id: id
80
+ @current_act.update_attributes! card_id: id
81
+ end
82
+
83
+ event :remove_empty_act,
84
+ :integrate_with_delay_final,
85
+ when: proc { |c| c.act_card? } do
86
+ if @current_act&.actions&.reload&.empty?
87
+ @current_act.delete
88
+ @current_act = nil
86
89
  end
87
90
  end
88
91
 
92
+
89
93
  def act_card?
90
94
  self == Card::ActManager.act_card
91
95
  end