card 1.93.13 → 1.94.0

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