card 1.15.7 → 1.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/card.gemspec +3 -2
  4. data/config/initializers/inflections.rb +1 -1
  5. data/db/migrate_core_cards/20150528084659_add_session_cardtype.rb +0 -1
  6. data/db/migrate_core_cards/20150601133433_add_recent_setting_session_card.rb +12 -0
  7. data/db/migrate_core_cards/20150610171702_add_debugger_session_card.rb +11 -0
  8. data/db/migrate_core_cards/20150611203506_rails_inflection_updates.rb +82 -0
  9. data/db/migrate_core_cards/20150627205133_fix_script_bootstrap_card_type.rb +7 -0
  10. data/db/migrate_core_cards/20150702130543_remove_edit_toolbar_pinned.rb +9 -0
  11. data/db/schema.rb +81 -81
  12. data/db/seed/new/card_actions.yml +12581 -1647
  13. data/db/seed/new/card_acts.yml +1 -1
  14. data/db/seed/new/card_changes.yml +39326 -7569
  15. data/db/seed/new/card_references.yml +518 -455
  16. data/db/seed/new/cards.yml +1547 -1291
  17. data/db/seed/test/fixtures/card_actions.yml +13700 -2717
  18. data/db/seed/test/fixtures/card_acts.yml +314 -272
  19. data/db/seed/test/fixtures/card_changes.yml +45409 -13573
  20. data/db/seed/test/fixtures/card_references.yml +1223 -1125
  21. data/db/seed/test/fixtures/cards.yml +2694 -2433
  22. data/db/seed/test/fixtures/file1.txt +1 -0
  23. data/db/seed/test/fixtures/file2.txt +1 -0
  24. data/db/version_core_cards.txt +1 -1
  25. data/lib/card.rb +23 -13
  26. data/lib/card/auth.rb +6 -6
  27. data/lib/card/cache.rb +24 -5
  28. data/lib/card/env.rb +10 -10
  29. data/lib/card/format.rb +29 -12
  30. data/lib/card/log.rb +5 -3
  31. data/lib/card/migration.rb +17 -41
  32. data/lib/card/name.rb +12 -0
  33. data/lib/card/reference.rb +11 -12
  34. data/lib/card/set.rb +59 -6
  35. data/lib/card/simplecov_helper.rb +6 -1
  36. data/lib/card/spec_helper.rb +3 -2
  37. data/lib/card/view_cache.rb +77 -0
  38. data/lib/cardio.rb +30 -22
  39. data/mod/01_core/format/html_format.rb +17 -9
  40. data/mod/01_core/layout/blank.html +1 -1
  41. data/mod/01_core/layout/default.html +6 -16
  42. data/mod/01_core/layout/modal.html +9 -0
  43. data/mod/01_core/layout/noside.html +5 -12
  44. data/mod/01_core/layout/simple.html +1 -1
  45. data/mod/01_core/set/all/collection.rb +57 -5
  46. data/mod/01_core/set/all/content.rb +5 -7
  47. data/mod/01_core/set/all/name.rb +8 -10
  48. data/mod/01_core/set/all/permissions.rb +1 -2
  49. data/mod/01_core/set/all/phases.rb +5 -13
  50. data/mod/01_core/set/all/references.rb +10 -10
  51. data/mod/01_core/set/all/rules.rb +2 -2
  52. data/mod/01_core/set/all/tracked_attributes.rb +5 -3
  53. data/mod/01_core/set/all/utils.rb +79 -9
  54. data/mod/01_core/set/all/view_cache.rb +9 -0
  55. data/mod/01_core/spec/format/html_format_spec.rb +2 -2
  56. data/mod/01_core/spec/set/all/collection_spec.rb +1 -1
  57. data/mod/01_history/lib/card/act.rb +3 -1
  58. data/mod/01_history/lib/card/action.rb +20 -12
  59. data/mod/01_history/lib/card/change.rb +12 -8
  60. data/mod/01_history/set/all/actions.rb +2 -2
  61. data/mod/01_history/set/all/content_history.rb +3 -2
  62. data/mod/01_history/set/all/history.rb +57 -19
  63. data/mod/02_basic_types/set/all/rss.rb +5 -6
  64. data/mod/{05_standard → 02_basic_types}/set/type/html.rb +4 -3
  65. data/mod/02_basic_types/set/type/plain_text.rb +1 -1
  66. data/mod/02_basic_types/set/type/pointer.rb +7 -4
  67. data/mod/02_basic_types/spec/set/type/pointer_spec.rb +21 -17
  68. data/mod/03_machines/lib/card/machine.rb +33 -31
  69. data/mod/03_machines/lib/javascript/script_card_menu.js.coffee +2 -10
  70. data/mod/03_machines/lib/javascript/wagn.js.coffee +10 -10
  71. data/mod/03_machines/lib/javascript/wagn_mod.js.coffee +87 -40
  72. data/mod/03_machines/lib/stylesheets/style_cards.scss +26 -28
  73. data/mod/03_machines/set/right/machine_output.rb +3 -3
  74. data/mod/03_machines/set/type/coffee_script.rb +6 -6
  75. data/mod/03_machines/set/type/css.rb +1 -1
  76. data/mod/03_machines/set/type/java_script.rb +5 -6
  77. data/mod/03_machines/spec/lib/shared_machine_examples.rb +3 -1
  78. data/mod/03_machines/spec/set/type/scss_spec.rb +9 -10
  79. data/mod/04_settings/lib/card/setting.rb +16 -14
  80. data/mod/04_settings/set/right/structure.rb +6 -0
  81. data/mod/04_settings/set/self/add_help.rb +1 -1
  82. data/mod/04_settings/set/self/autoname.rb +1 -1
  83. data/mod/04_settings/set/self/captcha.rb +1 -1
  84. data/mod/04_settings/set/self/default.rb +1 -1
  85. data/mod/04_settings/set/self/help.rb +1 -1
  86. data/mod/04_settings/set/self/input.rb +1 -1
  87. data/mod/04_settings/set/self/layout.rb +1 -1
  88. data/mod/04_settings/set/self/on_create.rb +1 -1
  89. data/mod/04_settings/set/self/on_delete.rb +1 -1
  90. data/mod/04_settings/set/self/on_update.rb +1 -1
  91. data/mod/04_settings/set/self/options.rb +1 -1
  92. data/mod/04_settings/set/self/options_label.rb +1 -1
  93. data/mod/04_settings/set/self/script.rb +1 -1
  94. data/mod/04_settings/set/self/structure.rb +1 -1
  95. data/mod/04_settings/set/self/style.rb +1 -1
  96. data/mod/04_settings/set/self/table_of_contents.rb +1 -1
  97. data/mod/04_settings/set/self/thanks.rb +1 -1
  98. data/mod/05_email/set/all/follow.rb +3 -21
  99. data/mod/05_email/set/all/notify.rb +20 -4
  100. data/mod/05_email/set/right/follow.rb +16 -18
  101. data/mod/05_email/set/self/follow.rb +1 -1
  102. data/mod/05_email/spec/set/all/follow_spec.rb +6 -13
  103. data/mod/05_standard/set/all/attach.rb +23 -9
  104. data/mod/05_standard/set/all/error.rb +5 -7
  105. data/mod/05_standard/set/all/event_viz.rb +10 -6
  106. data/mod/05_standard/set/all/links.rb +37 -13
  107. data/mod/05_standard/set/all/rich_html/content.rb +46 -18
  108. data/mod/05_standard/set/all/rich_html/editing.rb +29 -25
  109. data/mod/05_standard/set/all/rich_html/form.rb +17 -10
  110. data/mod/05_standard/set/all/rich_html/header.rb +26 -4
  111. data/mod/05_standard/set/all/rich_html/menu.rb +17 -34
  112. data/mod/05_standard/set/all/rich_html/modal.rb +50 -12
  113. data/mod/05_standard/set/all/rich_html/toolbar.rb +178 -186
  114. data/mod/05_standard/set/all/rich_html/wrapper.rb +44 -21
  115. data/mod/05_standard/set/rstar/rules.rb +43 -53
  116. data/mod/05_standard/set/self/all.rb +2 -1
  117. data/mod/05_standard/set/self/head.rb +2 -2
  118. data/mod/05_standard/set/self/signin.rb +18 -18
  119. data/mod/05_standard/set/self/stats.rb +14 -2
  120. data/mod/05_standard/set/type/search_type.rb +9 -4
  121. data/mod/05_standard/set/type/session.rb +12 -7
  122. data/mod/05_standard/set/type/set.rb +135 -18
  123. data/mod/05_standard/spec/chunk/include_spec.rb +15 -16
  124. data/mod/05_standard/spec/set/all/account_spec.rb +21 -21
  125. data/mod/05_standard/spec/set/all/event_viz_spec.rb +7 -7
  126. data/mod/05_standard/spec/set/all/history_spec.rb +54 -24
  127. data/mod/05_standard/spec/set/all/rich_html/editing_spec.rb +42 -40
  128. data/mod/05_standard/spec/set/rstar/rules_spec.rb +1 -1
  129. data/mod/05_standard/spec/set/type/search_type_spec.rb +9 -1
  130. data/mod/05_standard/spec/set/type/signup_spec.rb +42 -42
  131. data/mod/06_bootstrap/lib/stylesheets/bootstrap_cards.scss +6 -0
  132. data/mod/06_bootstrap/set/all/bootstrap/form.rb +4 -5
  133. data/mod/06_bootstrap/set/all/bootstrap/helper.rb +145 -0
  134. data/mod/06_bootstrap/set/all/rich_bootstrap.rb +0 -59
  135. data/spec/lib/card/action_spec.rb +1 -1
  136. data/spec/lib/card/log_spec.rb +7 -7
  137. data/spec/models/card/cardtype_spec.rb +1 -1
  138. data/spec/spec_helper.rb +1 -1
  139. metadata +31 -6
  140. data/mod/04_settings/set/self/comment.rb +0 -2
data/lib/card/name.rb CHANGED
@@ -41,5 +41,17 @@ class Card
41
41
  def code
42
42
  Card::Codename[ Card.fetch_id self ]
43
43
  end
44
+
45
+
46
+ def is_a_field_of? context_name
47
+ if context_name.present?
48
+ # Do I still equal myself after I've been relativised in the context of context_name?
49
+ relative_name = self.to_show(*context_name.to_name.parts).to_name
50
+ absolute_name = self.to_absolute_name(context_name)
51
+ relative_name.key != absolute_name.key
52
+ else
53
+ self.s.match /^\s*\+/
54
+ end
55
+ end
44
56
  end
45
57
  end
@@ -10,15 +10,15 @@ class Card::Reference < ActiveRecord::Base
10
10
  end
11
11
 
12
12
  class << self
13
-
13
+
14
14
  def delete_all_from card
15
15
  delete_all :referer_id => card.id
16
16
  end
17
-
17
+
18
18
  def delete_all_to card
19
19
  where( :referee_id => card.id ).update_all :present=>0, :referee_id => nil
20
20
  end
21
-
21
+
22
22
  def update_existing_key card, name=nil
23
23
  key = (name || card.name).to_name.key
24
24
  where( :referee_key => key ).update_all :present => 1, :referee_id => card.id
@@ -39,25 +39,24 @@ class Card::Reference < ActiveRecord::Base
39
39
  delete_all_from card
40
40
  delete_all_to card
41
41
  end
42
-
42
+
43
43
  def repair_missing_referees
44
- #FIXME - should treat trashed cards as not existing
45
- where( Card.where( :id=>arel_table[:referee_id], :trash=>false).exists.not ).update_all :referee_id=>nil
44
+ joins('LEFT JOIN cards ON card_references.referee_id = cards.id').where('(cards.id IS NULL OR cards.trash IS TRUE) AND referee_id IS NOT NULL').update_all :referee_id=>nil
46
45
  end
47
-
46
+
48
47
  def delete_missing_referers
49
- where( Card.where( :id=>arel_table[:referer_id], :trash=>false).exists.not ).delete_all
48
+ joins('LEFT JOIN cards ON card_references.referer_id = cards.id').where('cards.id IS NULL OR cards.trash IS TRUE').delete_all
50
49
  end
51
-
50
+
52
51
  def repair_all
53
52
  delete_missing_referers
54
-
53
+
55
54
  Card.where(:trash=>false).find_each do |card|
56
55
  Rails.logger.info "\nRepairing references for '#{card.name}' (id: #{card.id}) ... "
57
- card.update_references
56
+ card.update_references
58
57
  end
59
58
  end
60
-
59
+
61
60
  end
62
61
 
63
62
  end
data/lib/card/set.rb CHANGED
@@ -140,33 +140,86 @@ class Card
140
140
 
141
141
 
142
142
  def event event, opts={}, &final
143
+ perform_later = (opts[:before] == :subsequent) || (opts[:after] == :subsequent)
144
+ final_method = "#{event}_without_callbacks" #should be private?
143
145
  opts[:on] = [:create, :update ] if opts[:on] == :save
144
146
 
145
147
  Card.define_callbacks event
146
148
 
147
149
  class_eval do
148
- final_method = "#{event}_without_callbacks" #should be private?
149
150
  define_method final_method, &final
151
+ end
152
+
153
+ if perform_later
154
+ defer_method = "#{event}_perform_later"
155
+ define_event_perform_later_method event, defer_method
156
+ define_active_job event, final_method, opts[:queue_as]
157
+ define_event_method event, defer_method, opts
158
+ else
159
+ define_event_method event, final_method, opts
160
+ end
161
+ set_event_callbacks event, opts
162
+ end
163
+
164
+ def define_event_perform_later_method event, method_name
165
+ class_eval do
166
+ define_method method_name, proc {
167
+ s_attr = self.serializable_attributes.each_with_object({}) do |name, hash|
168
+ value = self.instance_variable_get("@#{name}")
169
+ hash[name] =
170
+ if Symbol === value # ActiveJob doesn't accept symbols as arguments
171
+ { :value => value.to_s, :symbol => true }
172
+ else
173
+ { :value => value }
174
+ end
175
+ end
176
+ Object.const_get(event.to_s.camelize).perform_later(self, s_attr)
177
+ }
178
+ end
179
+ end
150
180
 
181
+ def define_event_method event, call_method, opts
182
+ class_eval do
151
183
  define_method event do
152
184
  run_callbacks event do
153
185
  Card.with_logging :event, :message=>event, :context=>self.name, :details=>opts do
154
- send final_method
186
+ send call_method
155
187
  end
156
188
  end
157
189
  end
158
190
  end
159
-
160
- set_event_callbacks event, opts
161
191
  end
162
192
 
163
193
 
194
+ # creates an Active Job.
195
+ # The scheduled job gets the card object as argument and all serializable attributes of the card.
196
+ # (when the job is executed ActiveJob fetches the card from the database so all attributes get lost)
197
+ # @param name [String] the name for the ActiveJob child class
198
+ # @param final_method [String] the name of the card instance method to be queued
199
+ # @option queue [Symbol] (:default) the name of the queue
200
+ def define_active_job name, final_method, queue = :default
201
+ class_name = name.to_s.camelize
202
+ eval %{
203
+ class ::#{class_name} < ActiveJob::Base
204
+ queue_as #{queue}
205
+ end
206
+ }
207
+ Object.const_get(class_name).class_eval do
208
+ define_method :perform, proc { |card, attributes|
209
+ attributes.each do |name, args|
210
+ # symbols are not allowed so all symbols arrive here as strings
211
+ # convert strings that were symbols before back to symbols
212
+ value = args[:symbol] ? args[:value].to_sym : args[:value]
213
+ card.instance_variable_set("@#{name}", value )
214
+ end
215
+ card.send final_method
216
+ }
217
+ end
218
+ end
164
219
 
165
220
  #
166
221
  # ActiveCard support: accessing plus cards as attributes
167
222
  #
168
-
169
-
170
223
  def card_accessor *args
171
224
  options = args.extract_options!
172
225
  add_traits args, options.merge( :reader=>true, :writer=>true )
@@ -1,3 +1,7 @@
1
+ def is_in_mod? file,mod_path
2
+ mod_msg = "below pulled from #{Rails.root}/mod/#{mod_path}/"
3
+ file.src.join("") =~ /#{mod_msg}/
4
+ end
1
5
  def card_simplecov_filters
2
6
  add_filter 'spec/'
3
7
  add_filter '/config/'
@@ -15,7 +19,8 @@ def card_simplecov_filters
15
19
  src_file.filename =~ /mod\/#{mod}\// or
16
20
  (
17
21
  src_file.filename =~ /tmp\// and
18
- /\d+-(.+\.rb)/.match(src_file.filename) { |m| Dir["mod/#{mod}/**/#{m[1].gsub("-","/")}"].present? }
22
+ /\d+-(.+\.rb)/.match(src_file.filename) { |m| Dir["mod/#{mod}/**/#{m[1].gsub("-","/")}"].present? } and
23
+ is_in_mod? src_file,mod
19
24
  )
20
25
  end
21
26
  end
@@ -2,7 +2,7 @@ module SpecHelper
2
2
  end
3
3
  module Card::SpecHelper
4
4
 
5
- include ActionDispatch::Assertions::SelectorAssertions
5
+ include Rails::Dom::Testing::Assertions::SelectorAssertions
6
6
  #~~~~~~~~~ HELPER METHODS ~~~~~~~~~~~~~~~#
7
7
 
8
8
  def login_as user
@@ -19,7 +19,8 @@ module Card::SpecHelper
19
19
  end
20
20
 
21
21
  def assert_view_select(view_html, *args, &block)
22
- node = HTML::Document.new(view_html).root
22
+ node = Nokogiri::HTML::Document.parse(view_html).root
23
+ #node = HTML::Document.new(view_html).root
23
24
  if block_given?
24
25
  assert_select node, *args, &block
25
26
  else
@@ -0,0 +1,77 @@
1
+ class Card
2
+ module ViewCache
3
+ class << self
4
+ SIZE = 500
5
+ LIMIT = 1000 # reduce cache size to SIZE if LIMIT is reached
6
+ CNT_KEY = 'view_cache_cnt'
7
+ FREQUENCY_KEY = 'view_cache_frequency'
8
+
9
+ def cache
10
+ Card::Cache[Card::ViewCache]
11
+ end
12
+
13
+ def increment_cnt
14
+ cache.write(CNT_KEY, count+1)
15
+ end
16
+
17
+ def count
18
+ cache.read(CNT_KEY) || 0
19
+ end
20
+
21
+ def reduce_cache
22
+ update_frequency do |freq|
23
+ cnts_with_key = freq.keys.map { |key| [freq[key], key] }
24
+ index = 1
25
+ SortedSet.new(cnts_with_key).each do |cnt, key|
26
+ if index < (LIMIT - SIZE)
27
+ cache.delete(key)
28
+ freq.delete(key)
29
+ else
30
+ freq[key] = 0
31
+ end
32
+ index += 1
33
+ end
34
+ end
35
+ end
36
+
37
+ def update_frequency
38
+ freq = cache.read(FREQUENCY_KEY) || {}
39
+ yield(freq)
40
+ cache.write(FREQUENCY_KEY, freq)
41
+ end
42
+
43
+ def fetch(format, view, args, &block)
44
+ if !Card.config.view_cache || !format.view_caching? || !format.main? || (view != :open && view != :content) || format.class != HtmlFormat
45
+ return block.call
46
+ end
47
+
48
+ roles = Card::Auth.current.all_roles.sort.join '_'
49
+ key = "view_#{view}_#{format.card.key}_args_#{Card::Cache.obj_to_key(args)}_roles_#{roles}"
50
+
51
+ if !cache.exist?(key)
52
+ increment_cnt
53
+ reduce_cache if count > LIMIT
54
+ end
55
+
56
+ update_frequency do |freq|
57
+ freq[key] ||= 0
58
+ freq[key] += 1
59
+ end
60
+
61
+ if Card.config.view_cache == 'debug'
62
+ if cache.exist? key
63
+ "fetched from view cache: #{cache.read key}"
64
+ else
65
+ "written to view cache: #{cache.fetch(key, &block)}"
66
+ end
67
+ else
68
+ cache.fetch(key, &block)
69
+ end
70
+ end
71
+
72
+ def reset hard=false
73
+ cache.reset hard
74
+ end
75
+ end
76
+ end
77
+ end
data/lib/cardio.rb CHANGED
@@ -28,28 +28,37 @@ module Cardio
28
28
  config.autoload_paths += Dir["#{gem_root}/lib/**/"]
29
29
  config.autoload_paths += Dir["#{root}/mod/*/lib/**/"]
30
30
 
31
- config.read_only = !!ENV['WAGN_READ_ONLY']
32
- config.allow_inline_styles = false
31
+ set_default_value config, :read_only, !!ENV['WAGN_READ_ONLY']
32
+ set_default_value config, :allow_inline_styles, false
33
33
 
34
- config.recaptcha_public_key = nil
35
- config.recaptcha_private_key = nil
36
- config.recaptcha_proxy = nil
34
+ set_default_value config, :recaptcha_public_key, nil
35
+ set_default_value config, :recaptcha_private_key, nil
36
+ set_default_value config, :recaptcha_proxy, nil
37
37
 
38
- config.cache_store = :file_store, 'tmp/cache'
39
- config.override_host = nil
40
- config.override_protocol = nil
38
+ set_default_value config, :cache_store, :file_store, 'tmp/cache'
39
+ set_default_value config, :override_host, nil
40
+ set_default_value config, :override_protocol, nil
41
41
 
42
- config.no_authentication = false
43
- config.files_web_path = 'files'
42
+ set_default_value config, :no_authentication, false
43
+ set_default_value config, :files_web_path, 'files'
44
44
 
45
- config.max_char_count = 200
46
- config.max_depth = 20
47
- config.email_defaults = nil
45
+ set_default_value config, :max_char_count, 200
46
+ set_default_value config, :max_depth, 20
47
+ set_default_value config, :email_defaults, nil
48
48
 
49
- config.token_expiry = 2.days
50
- config.revisions_per_page = 10
51
- config.space_last_in_multispace = true
52
- config.closed_search_limit = 50
49
+ set_default_value config, :token_expiry, 2.days
50
+ set_default_value config, :revisions_per_page, 10
51
+ set_default_value config, :space_last_in_multispace, true
52
+ set_default_value config, :closed_search_limit, 50
53
+
54
+ set_default_value config, :view_cache, false
55
+ end
56
+
57
+ # In production mode set_config gets called twice.
58
+ # The second call overrides all deck config settings
59
+ # so don't change settings here if they already exist
60
+ def set_default_value config, setting, *value
61
+ config.send("#{setting}=", *value) unless config.respond_to? setting
53
62
  end
54
63
 
55
64
 
@@ -80,10 +89,8 @@ module Cardio
80
89
 
81
90
  def add_path path, options={}
82
91
  root = options.delete(:root) || gem_root
83
- gem_path = File.join( root, path )
84
- with = options.delete(:with)
85
- with = with ? File.join(root, with) : gem_path
86
- paths[path] = Rails::Paths::Path.new(paths, gem_path, with, options)
92
+ options[:with] = File.join(root, (options[:with] || path) )
93
+ paths.add path, options
87
94
  end
88
95
 
89
96
  def future_stamp
@@ -126,10 +133,11 @@ module Cardio
126
133
  def schema_mode type
127
134
  new_suffix = Cardio.schema_suffix type
128
135
  original_suffix = ActiveRecord::Base.table_name_suffix
129
-
130
136
  ActiveRecord::Base.table_name_suffix = new_suffix
137
+ ActiveRecord::SchemaMigration.reset_table_name
131
138
  yield
132
139
  ActiveRecord::Base.table_name_suffix = original_suffix
140
+ ActiveRecord::SchemaMigration.reset_table_name
133
141
  end
134
142
 
135
143
  def schema type=nil
@@ -6,12 +6,12 @@ class Card
6
6
  Format.register :html
7
7
  class HtmlFormat < Format
8
8
  include Diff
9
-
9
+
10
10
  attr_accessor :options_need_save, :start_time, :skip_autosave
11
11
 
12
12
  # builtin layouts allow for rescue / testing
13
13
  LAYOUTS = Loader.load_layouts.merge 'none' => '{{_main}}'
14
-
14
+
15
15
  # helper methods for layout view
16
16
  def get_layout_content
17
17
  Auth.as_bot do
@@ -39,11 +39,11 @@ class Card
39
39
  "<h1>Unknown layout: #{name}</h1>Built-in Layouts: #{LAYOUTS.keys.join(', ')}"
40
40
  end
41
41
  end
42
-
42
+
43
43
  def get_inclusion_defaults nested_card
44
44
  {:view => (nested_card.rule( :default_html_view ) || :titled) }
45
45
  end
46
-
46
+
47
47
  def default_item_view
48
48
  :closed
49
49
  end
@@ -53,13 +53,13 @@ class Card
53
53
  when String; content
54
54
  when Array ; content.compact.join "\n"
55
55
  end
56
- end
56
+ end
57
57
 
58
58
  def html_escape_except_quotes s
59
59
  # to be used inside single quotes (makes for readable json attributes)
60
60
  s.to_s.gsub(/&/, "&amp;").gsub(/\'/, "&apos;").gsub(/>/, "&gt;").gsub(/</, "&lt;")
61
61
  end
62
-
62
+
63
63
  #### -------------------- additional helpers ---------------- ###
64
64
 
65
65
  # session history helpers: we keep a history stack so that in the case of
@@ -100,7 +100,7 @@ class Card
100
100
  uri = path(uri) if Hash === uri
101
101
  session[:interrupted_action] = uri
102
102
  end
103
-
103
+
104
104
  def interrupted_action
105
105
  session.delete :interrupted_action
106
106
  end
@@ -113,10 +113,18 @@ class Card
113
113
 
114
114
 
115
115
  def main?
116
- if Env.ajax?
116
+ if show_layout?
117
+ @depth == 1 && @mainline #assumes layout includes {{_main}}
118
+ else
117
119
  @depth == 0 && params[:is_main]
120
+ end
121
+ end
122
+
123
+ def focal? # meaning the current card is the requested card
124
+ if show_layout?
125
+ main?
118
126
  else
119
- @depth == 1 && @mainline #assumes layout includes {{_main}}
127
+ @depth == 0
120
128
  end
121
129
  end
122
130
  end
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE HTML>
2
2
  <html>
3
- <head> {{*head}} </head>
3
+ <head> {{*head|core}} </head>
4
4
  <body id="wagn"> {{_main}} </body>
5
5
  </html>
@@ -1,20 +1,10 @@
1
1
  <!DOCTYPE HTML>
2
2
  <html>
3
- <head>
4
- {{*head}}
5
- </head>
6
-
7
- <body id="wagn">
8
- <div id="menu">
9
- [[/ | Home]] [[/recent | Recent]] {{*navbox}} {{*account links}}
10
- </div>
11
-
12
- <div id="primary">
13
- {{_main}}
14
- </div>
15
-
16
- <div id="secondary">
17
- {{*sidebar}}
18
- </div>
3
+ <head>{{*head|core}}</head>
4
+ <body>
5
+ <header>{{*header|core}}</header>
6
+ <article>{{_main|open}}</article>
7
+ <aside>{{*sidebar|core}}</aside>
8
+ <footer>{{*footer|core}}</footer>
19
9
  </body>
20
10
  </html>