card 1.92 → 1.92.1

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