card 1.93.13 → 1.94.0

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/config/initializers/01_core_extensions/persistent_identifiers.rb +8 -0
  4. data/config/locales/de.yml +1 -0
  5. data/config/locales/en.yml +1 -0
  6. data/lib/card.rb +2 -1
  7. data/lib/card/cache.rb +1 -1
  8. data/lib/card/content/clean.rb +6 -4
  9. data/lib/card/format/error.rb +1 -1
  10. data/lib/card/format/render.rb +1 -1
  11. data/lib/card/mod.rb +6 -1
  12. data/lib/card/mod/loader.rb +2 -0
  13. data/lib/card/name.rb +25 -5
  14. data/lib/card/query/attributes.rb +13 -8
  15. data/lib/card/set/event.rb +1 -1
  16. data/lib/card/tasks/card.rake +12 -0
  17. data/lib/card/tasks/card/migrate.rake +2 -0
  18. data/lib/card/view/options.rb +2 -1
  19. data/lib/cardio.rb +6 -6
  20. data/lib/cardio/utils.rb +30 -0
  21. data/mod/account/set/self/signin.rb +3 -13
  22. data/mod/account/set/type/signup.rb +1 -1
  23. data/mod/account/spec/set/self/signin_spec.rb +1 -1
  24. data/mod/basic_formats/set/all/base.rb +11 -3
  25. data/mod/basic_formats/set/all/json.rb +1 -0
  26. data/mod/basic_formats/set/self/head.rb +2 -3
  27. data/mod/bootstrap/db/migrate_core_cards/20170719163733_update_bootswatch_themes_to_4_beta.rb +2 -95
  28. data/mod/bootstrap/db/migrate_core_cards/lib/skin.rb +94 -0
  29. data/mod/bootstrap/script/update_skin_thumbnails.rb +9 -0
  30. data/mod/carrierwave/set/type/image.rb +1 -1
  31. data/mod/core/chunk/query_reference.rb +9 -2
  32. data/mod/core/set/all/event_conditions.rb +18 -8
  33. data/mod/core/set/all/fetch_helper.rb +11 -11
  34. data/mod/core/set/all/utils.rb +0 -12
  35. data/mod/core/spec/format/html_format_spec.rb +3 -3
  36. data/mod/core/spec/set/all/event_conditions_spec.rb +15 -0
  37. data/mod/core/spec/set/all/name_spec.rb +7 -0
  38. data/mod/core/spec/set/all/name_validations_spec.rb +0 -10
  39. data/mod/core/spec/set/all/rename_spec.rb +2 -2
  40. data/mod/pointer/set/abstract/02_pointer.rb +4 -0
  41. data/mod/search/set/abstract/00_filter_helper.rb +1 -1
  42. data/mod/search/set/abstract/02_search_params.rb +18 -0
  43. data/mod/search/set/abstract/search.rb +1 -1
  44. data/mod/search/set/self/navbox.rb +2 -2
  45. data/mod/search/set/self/search.rb +1 -19
  46. data/mod/search/spec/set/self/search_spec.rb +1 -1
  47. data/mod/standard/set/all/error.rb +6 -6
  48. data/mod/standard/set/all/rich_html/content.rb +2 -27
  49. data/mod/standard/set/all/rich_html/editing.rb +1 -1
  50. data/mod/standard/set/all/rich_html/title.rb +39 -0
  51. data/mod/standard/set/all/rich_html/toolbar.rb +1 -1
  52. data/mod/standard/set/type/cardtype.rb +8 -2
  53. data/mod/standard/spec/{chunk → content/chunk}/include_spec.rb +5 -5
  54. data/mod/standard/spec/{chunk → content/chunk}/link_spec.rb +1 -1
  55. data/mod/standard/spec/{chunk → content/chunk}/query_reference_spec.rb +0 -0
  56. metadata +11 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: '0565498a57c12cee5413854a7abdcd5f419ae185'
4
- data.tar.gz: 768181a64e6a5a025969c04eb256c23533e0ce07
3
+ metadata.gz: 8108ea9c272fbf1d35f39674c2fabc4f422154b9
4
+ data.tar.gz: 1c554ea42be6ddfded470c10d9c32baf1ddd686a
5
5
  SHA512:
6
- metadata.gz: 1e854a627aefe2fff81b0af9e64954d96c3122da3c2a67e00ac9dc780d5c0638562fcb99364bc148895aa1f759e6cd67018ca1d1154f32ddc7570bb2d5dbf0cf
7
- data.tar.gz: b7f5efe77ba0531054c4f378db9b1ef375d350ee831316665ae574ce5a24067c9e85367596552301fd8ef43b37ecae764016a3de7ea0e93adc22485dccc8ab4a
6
+ metadata.gz: '019228759816d0c42326e921ecfbd1393328b6e20c7e01fcc5f894593699481b87b604976b5a9ffaf23bbcee9295aa1d2c059089a6db0f6b43b87ff8c0a0cf8d'
7
+ data.tar.gz: 0c75e8da55c96f4b98f43e26c23666eeb8d832b434993f60cd55f541f79590ba3cd1bff1ab9e562474b7afc62ab68d2b75e6940fe1bd383fe03555d7b64695a0
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.13
1
+ 0.4.0
@@ -1,12 +1,20 @@
1
1
  module CoreExtensions
2
2
  # methods for codenames and numerical ids
3
+ # included in Integer and Symbol
3
4
  module PersistentIdentifier
5
+ # interpret symbol/integer as codename/id
4
6
  def card
5
7
  Card[self]
6
8
  end
7
9
 
10
+ # interpret symbol/integer as codename/id
8
11
  def cardname
9
12
  Card.quick_fetch(self).name
10
13
  end
14
+
15
+ # don't interpret symbol/integer as codename/id
16
+ def to_name
17
+ Card::Name.new to_s
18
+ end
11
19
  end
12
20
  end
@@ -421,6 +421,7 @@ de:
421
421
  cards_exist: Entschuldigung, diese Karten muss ein Kartentyp bleiben, solange es noch %{cardname}-Karten gibt.
422
422
  add_card: Füge %{cardname} hinzu
423
423
  error_cant_alter: kann dieseh Typ nicht ändern; es gibt noch %{name}-Karten
424
+ error_invalid_character_in_cardtype: "die folgenden Zeichen sind nicht erlaubt: %{banned}"
424
425
  list:
425
426
  type_right: benötigt einen Kartentypnamen als rechten Teil
426
427
  conflict_item_type: name conflicts with list items' type; delete content first
@@ -431,6 +431,7 @@ en:
431
431
  cards_exist: Sorry, this card must remain a Cardtype so long as there are %{cardname} cards.
432
432
  add_card: Add %{cardname}
433
433
  error_cant_alter: can't alter this type; %{name} cards still exist
434
+ error_invalid_character_in_cardtype: "may not contain any of the following characters: %{banned}"
434
435
  list:
435
436
  type_right: must have a cardtype name as right part
436
437
  conflict_item_type: name conflicts with list items' type; delete content first
@@ -139,7 +139,8 @@ class Card < ApplicationRecord
139
139
  # :remove_rule_stash,
140
140
  :last_action_id_before_edit,
141
141
  :only_storage_phase, # used to save subcards
142
- :changed_attributes
142
+ :changed_attributes,
143
+ :skip_event
143
144
  )
144
145
 
145
146
  def serializable_attributes
@@ -97,7 +97,7 @@ class Card
97
97
  # (the non-standard caches)
98
98
  def reset_other
99
99
  Card::Codename.reset_cache
100
- Card.delete_tmp_files
100
+ Cardio.delete_tmp_files!
101
101
  end
102
102
 
103
103
  # generate a cache key from an object
@@ -10,14 +10,16 @@ class Card
10
10
 
11
11
  # allowed attributes
12
12
  allowed_tags.merge!(
13
- "a" => %w(href title target),
14
- "img" => %w(src alt title),
13
+ "a" => %w[href title target],
14
+ "img" => %w[src alt title],
15
15
  "code" => ["lang"],
16
16
  "blockquote" => ["cite"]
17
17
  )
18
18
 
19
19
  if Card.config.allow_inline_styles
20
- allowed_tags["table"] += %w(cellpadding align border cellspacing)
20
+ allowed_tags["table"] += %w[cellpadding align border cellspacing data-mce-style]
21
+ allowed_tags["td"] += %w[scope data-mce-style]
22
+ allowed_tags["th"] += %w[scope data-mce-style]
21
23
  end
22
24
 
23
25
  allowed_tags.each_key do |k|
@@ -61,7 +63,7 @@ class Card
61
63
  return ['"', nil] unless all_attributes =~ /\b#{attrib}\s*=\s*(?=(.))/i
62
64
  q = '"'
63
65
  rest_value = $'
64
- if (idx = %w(' ").index Regexp.last_match(1))
66
+ if (idx = %w[' "].index Regexp.last_match(1))
65
67
  q = Regexp.last_match(1)
66
68
  end
67
69
  reg_exp = ATTR_VALUE_RE[idx || 2]
@@ -14,7 +14,7 @@ class Card
14
14
 
15
15
  def error_cardname
16
16
  if card&.name.present?
17
- card.name
17
+ safe_name
18
18
  else
19
19
  I18n.t :no_cardname, scope: [:lib, :card, :format, :error]
20
20
  end
@@ -49,7 +49,7 @@ class Card
49
49
  def add_debug_info view, method, rendered
50
50
  return rendered unless show_debug_info?
51
51
  <<-HTML
52
- <view-debug view='#{card.name}##{view}' src='#{pretty_path method.source_location}' module='#{method.owner}'/>
52
+ <view-debug view='#{safe_name}##{view}' src='#{pretty_path method.source_location}' module='#{method.owner}'/>
53
53
  #{rendered}
54
54
  HTML
55
55
  end
@@ -52,7 +52,12 @@ class Card
52
52
  module Mod
53
53
  class << self
54
54
  def load
55
- Loader.load_mods
55
+ return if ENV["CARD_MODS"] == "none"
56
+ if Card.take
57
+ Loader.load_mods
58
+ else
59
+ Rails.logger.warn "empty database"
60
+ end
56
61
  end
57
62
 
58
63
  # @return an array of Rails::Path objects
@@ -44,6 +44,8 @@ class Card
44
44
  load_formats
45
45
  SetLoader.new.load
46
46
  load_initializers
47
+ # rescue
48
+ # raise Card::Error, "unrescued error loading mods"
47
49
  end
48
50
 
49
51
  def load_chunks
@@ -19,15 +19,35 @@ class Card
19
19
  def [] *cardish
20
20
  cardish = cardish.first if cardish.size <= 1
21
21
  case cardish
22
- when Card then cardish.name
23
- when Symbol, Integer then Card.fetch_name(cardish)
24
- when Array then compose cardish
25
- else cardish.to_name
22
+ when Card then cardish.name
23
+ when Symbol, Integer then Card.fetch_name(cardish)
24
+ when Array then compose cardish
25
+ when String, NilClass then new cardish
26
+ else
27
+ raise ArgumentError, "#{cardish.class} not supported as name identifier"
26
28
  end
27
29
  end
28
30
 
31
+ def new str, validated_parts=nil
32
+ return compose str if str.is_a?(Array)
33
+
34
+ str = str.to_s
35
+ if !validated_parts && str.include?(joint)
36
+ compose Cardname.split_parts(str)
37
+ elsif special_prefix?(str)
38
+ Card.fetch_name str # handles ~ and :
39
+ else
40
+ super str
41
+ end
42
+ end
43
+
44
+ def special_prefix? str
45
+ str.start_with? "~", ":"
46
+ end
47
+
29
48
  def compose parts
30
- new parts.flatten.map { |part| self[part] }.join(joint)
49
+ name_parts = parts.flatten.map { |part| self[part] }
50
+ new name_parts.join(joint), true
31
51
  end
32
52
 
33
53
  def url_key_to_standard key
@@ -27,18 +27,11 @@ class Card
27
27
  # content.
28
28
  # Example: { match: "name or content" } vs. { name: ["match", "a name"] }
29
29
  def match val
30
- cxn = connection
31
30
  val.gsub!(/[^#{Card::Name::OK4KEY_RE}]+/, " ")
32
31
  return nil if val.strip.empty?
33
32
 
34
33
  val_list = val.split(/\s+/).map do |v|
35
- name_or_content = [
36
- "replace(#{table_alias}.name,'+',' ')",
37
- "#{table_alias}.db_content"
38
- ].map do |field|
39
- %(#{field} #{cxn.match quote("[[:<:]]#{v}[[:>:]]")})
40
- end
41
- or_join name_or_content
34
+ name_or_content_match v
42
35
  end
43
36
  add_condition and_join(val_list)
44
37
  end
@@ -66,6 +59,18 @@ class Card
66
59
 
67
60
  private
68
61
 
62
+ def name_or_content_match val
63
+ cxn = connection
64
+ or_join(
65
+ [field_match("replace(#{table_alias}.name,'+',' ')", val, cxn),
66
+ field_match("#{table_alias}.db_content", val, cxn)]
67
+ )
68
+ end
69
+
70
+ def field_match field, val, cxn
71
+ %(#{field} #{cxn.match quote("[[:<:]]#{val}[[:>:]]")})
72
+ end
73
+
69
74
  def name_like patterns, extra_cond=""
70
75
  likes =
71
76
  Array(patterns).map do |pat|
@@ -98,7 +98,7 @@ class Card
98
98
  def set_event_callback object_method, kind, event, opts
99
99
  Card.class_eval do
100
100
  set_callback object_method, kind, event,
101
- prepend: true, if: proc { |c| c.event_applies?(opts) }
101
+ prepend: true, if: proc { |c| c.event_applies?(event, opts) }
102
102
  end
103
103
  end
104
104
  end
@@ -105,4 +105,16 @@ namespace :card do
105
105
  task reset_machine_output: :environment do
106
106
  Card.reset_all_machines
107
107
  end
108
+
109
+ desc "refresh machine output"
110
+ task refresh_machine_output: :environment do
111
+ Card.reset_all_machines
112
+ Card::Auth.as_bot do
113
+ [%i[all script],
114
+ %i[all style],
115
+ %i[script_html5shiv_printshiv]].each do |name_parts|
116
+ Card[*name_parts].update_machine_output
117
+ end
118
+ end
119
+ end
108
120
  end
@@ -39,6 +39,7 @@ namespace :card do
39
39
  desc "migrate structure"
40
40
  task structure: :environment do
41
41
  ENV["SCHEMA"] ||= "#{Cardio.gem_root}/db/schema.rb"
42
+ ActiveRecord::Base.dump_schema_after_migration = false
42
43
  Cardio.schema_mode(:structure) do |paths|
43
44
  ActiveRecord::Migrator.migrations_paths = paths
44
45
  ActiveRecord::Migrator.migrate paths, version
@@ -49,6 +50,7 @@ namespace :card do
49
50
 
50
51
  desc "migrate core cards"
51
52
  task core_cards: :environment do
53
+ ActiveRecord::Base.dump_schema_after_migration = false
52
54
  require "card/migration/core"
53
55
  run_card_migration :core_cards
54
56
  end
@@ -41,7 +41,8 @@ class Card
41
41
  ], # (Symbol<:always, :standard, :never>)
42
42
  none: [
43
43
  :skip_perms, # do not check permissions for this view (Boolean)
44
- :main_view # this is main view of page (Boolean)
44
+ :main_view, # this is main view of page (Boolean)
45
+ :layout #
45
46
  ]
46
47
  }
47
48
  # Note: option values are strings unless otherwise noted
@@ -4,17 +4,15 @@ require "active_support/core_ext/numeric/time"
4
4
  djar = "delayed_job_active_record"
5
5
  require djar if Gem::Specification.find_all_by_name(djar).any?
6
6
  require "cardio/schema.rb"
7
+ require "cardio/utils.rb"
7
8
 
8
9
  ActiveSupport.on_load :after_card do
9
- if Card.take
10
- Card::Mod.load
11
- else
12
- Rails.logger.warn "empty database"
13
- end
10
+ Card::Mod.load
14
11
  end
15
12
 
16
13
  module Cardio
17
14
  extend Schema
15
+ extend Utils
18
16
  CARD_GEM_ROOT = File.expand_path("../..", __FILE__)
19
17
 
20
18
  mattr_reader :paths, :config
@@ -27,7 +25,9 @@ module Cardio
27
25
  def default_configs
28
26
  {
29
27
  read_only: read_only?,
30
- allow_inline_styles: false,
28
+
29
+ # if you disable inline styles tinymce's formatting options stop working
30
+ allow_inline_styles: true,
31
31
 
32
32
  recaptcha_public_key: nil,
33
33
  recaptcha_private_key: nil,
@@ -0,0 +1,30 @@
1
+ module Cardio
2
+ # Utilities that may need to be run even when mods are not loaded.
3
+ module Utils
4
+ def seed_test_db
5
+ system "env RAILS_ENV=test bundle exec rake db:fixtures:load"
6
+ end
7
+
8
+ # deletes tmp directory within files directory
9
+ # It's here because it gets called as part of cache clearing, which sometimes gets
10
+ # called in a context where card mods are not loaded.
11
+ # Why does cache clearing need to do this??
12
+ def delete_tmp_files! id=nil
13
+ raise "no files directory" unless files_dir
14
+ delete_tmp_files id
15
+ rescue StandardError
16
+ Rails.logger.info "failed to remove tmp files"
17
+ end
18
+
19
+ private
20
+
21
+ def delete_tmp_files id=nil
22
+ dir = [files_dir, "tmp", id.to_s].compact.join "/"
23
+ FileUtils.rm_rf dir, secure: true
24
+ end
25
+
26
+ def files_dir
27
+ @files_dir ||= Cardio.paths["files"].existent.first
28
+ end
29
+ end
30
+ end
@@ -24,7 +24,7 @@ format :html do
24
24
  end
25
25
 
26
26
  view :core, cache: :never do
27
- voo.structure = true
27
+ voo.edit_structure = [signin_field(:email), signin_field(:password)]
28
28
  with_nest_mode :edit do
29
29
  card_form :update, recaptcha: :off do
30
30
  [
@@ -37,8 +37,7 @@ format :html do
37
37
  end
38
38
 
39
39
  def hidden_signin_fields
40
- hidden_field_tag :success,
41
- "REDIRECT: #{Env.interrupted_action || '*previous'}"
40
+ hidden_field_tag :success, "REDIRECT: #{Env.interrupted_action || '*previous'}"
42
41
  end
43
42
 
44
43
  view :signin_buttons do
@@ -66,9 +65,8 @@ format :html do
66
65
 
67
66
  # FORGOT PASSWORD
68
67
  view :edit do
69
- @forgot_password = true
70
68
  voo.title ||= card.i18n_signin(:forgot_password)
71
- voo.structure ||= true
69
+ voo.edit_structure = [signin_field(:email)]
72
70
  voo.hide :help
73
71
  Auth.as_bot { super() }
74
72
  end
@@ -85,14 +83,6 @@ format :html do
85
83
  button_tag text, situation: "primary"
86
84
  end
87
85
 
88
- view :content_formgroup do
89
- fields = [signin_field(:email)]
90
- fields << signin_field(:password) unless @forgot_password
91
- voo.edit_structure = fields
92
-
93
- super()
94
- end
95
-
96
86
  def signin_field name
97
87
  nest_name = "".to_name.trait(name)
98
88
  [nest_name, { title: name.to_s, view: "titled",
@@ -48,7 +48,7 @@ format :html do
48
48
  end
49
49
 
50
50
  def signup_line
51
- [ "<strong>#{card.name}</strong>",
51
+ [ "<strong>#{safe_name}</strong>",
52
52
  ("was" unless anonymous_signup?),
53
53
  "signed up on #{format_date card.created_at}"
54
54
  ].compact.join " "
@@ -2,7 +2,7 @@
2
2
 
3
3
  # FIXME: need more specific assertions
4
4
 
5
- describe Card::Set::Self::Signin do
5
+ RSpec.describe Card::Set::Self::Signin do
6
6
  before do
7
7
  @card = Card[:signin]
8
8
  end
@@ -9,6 +9,10 @@ format do
9
9
  name_variant card.name
10
10
  end
11
11
 
12
+ def safe_name
13
+ card&.name
14
+ end
15
+
12
16
  def name_variant name
13
17
  voo.variant ? name.to_name.vary(voo.variant) : name
14
18
  end
@@ -18,7 +22,7 @@ format do
18
22
  view(:url, closed: true, perms: :none) { card_url _render_linkname }
19
23
 
20
24
  view :title, closed: true, perms: :none do
21
- name_variant title_in_context(voo.title)
25
+ name_variant(title_in_context(voo.title))
22
26
  end
23
27
 
24
28
  view :url_link, closed: true, perms: :none do
@@ -66,8 +70,12 @@ format do
66
70
  # CONTENT VIEWS
67
71
 
68
72
  view :raw do
69
- scard = voo.structure ? Card[voo.structure] : card
70
- scard ? scard.content : _render_blank
73
+ structure_card&.content || _render_blank
74
+ end
75
+
76
+ def structure_card
77
+ return nil if voo.structure == true
78
+ voo.structure ? Card[voo.structure] : card
71
79
  end
72
80
 
73
81
  view :core, closed: true do