card 1.15.2 → 1.15.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/db/migrate_core_cards/20150528084659_add_session_cardtype.rb +15 -0
  4. data/db/seed/new/card_actions.yml +342 -314
  5. data/db/seed/new/card_acts.yml +1 -1
  6. data/db/seed/new/card_changes.yml +1284 -1199
  7. data/db/seed/new/card_references.yml +664 -622
  8. data/db/seed/new/cards.yml +1355 -1278
  9. data/db/seed/test/fixtures/card_actions.yml +1239 -1204
  10. data/db/seed/test/fixtures/card_acts.yml +281 -275
  11. data/db/seed/test/fixtures/card_changes.yml +4127 -4022
  12. data/db/seed/test/fixtures/card_references.yml +1338 -1296
  13. data/db/seed/test/fixtures/cards.yml +2635 -2540
  14. data/db/version_core_cards.txt +1 -1
  15. data/lib/card/core_ext.rb +11 -7
  16. data/lib/card/format.rb +1 -1
  17. data/lib/card/name.rb +1 -1
  18. data/lib/card/set.rb +47 -47
  19. data/lib/card/simplecov_helper.rb +2 -2
  20. data/lib/card/spec_helper.rb +17 -7
  21. data/lib/card/view_name.rb +44 -0
  22. data/mod/01_core/chunk/include.rb +1 -1
  23. data/mod/01_core/set/all/collection.rb +90 -7
  24. data/mod/01_core/spec/set/all/collection_spec.rb +37 -3
  25. data/mod/01_history/lib/card/act.rb +15 -11
  26. data/mod/01_history/lib/card/action.rb +38 -38
  27. data/mod/01_history/set/all/history.rb +8 -4
  28. data/mod/02_basic_types/set/type/pointer.rb +29 -28
  29. data/mod/03_machines/lib/javascript/wagn_mod.js.coffee +39 -0
  30. data/mod/03_machines/lib/stylesheets/style_cards.scss +6 -1
  31. data/mod/05_email/set/all/notify.rb +47 -49
  32. data/mod/05_email/set/self/follow_defaults.rb +7 -7
  33. data/mod/05_email/set/type_plus_right/user/follow.rb +1 -1
  34. data/mod/05_standard/set/all/error.rb +1 -1
  35. data/mod/05_standard/set/all/links.rb +1 -1
  36. data/mod/05_standard/set/all/rich_html/content.rb +23 -21
  37. data/mod/05_standard/set/all/rich_html/editing.rb +64 -8
  38. data/mod/05_standard/set/all/rich_html/form.rb +26 -26
  39. data/mod/05_standard/set/all/rich_html/header.rb +2 -2
  40. data/mod/05_standard/set/all/rich_html/menu.rb +9 -10
  41. data/mod/05_standard/set/all/rich_html/toolbar.rb +100 -71
  42. data/mod/05_standard/set/all/rich_html/wrapper.rb +6 -0
  43. data/mod/05_standard/set/right/discussion.rb +3 -0
  44. data/mod/05_standard/set/rstar/rules.rb +5 -24
  45. data/mod/05_standard/set/type/cardtype.rb +31 -2
  46. data/mod/05_standard/set/type/session.rb +29 -0
  47. data/mod/05_standard/set/type/set.rb +1 -1
  48. data/mod/05_standard/spec/set/all/rich_html/editing_spec.rb +60 -0
  49. data/mod/05_standard/spec/set/all/rich_html/form_spec.rb +6 -6
  50. data/mod/05_standard/spec/set/type/cardtype_spec.rb +15 -1
  51. data/mod/06_bootstrap/lib/javascript/bootstrap_modal_wagn.js +27 -0
  52. data/mod/06_bootstrap/set/all/rich_bootstrap.rb +4 -3
  53. data/mod/06_bootstrap/set/self/bootstrap_js.rb +3 -1
  54. metadata +8 -2
@@ -1 +1 @@
1
- 20150510031118
1
+ 20150528084659
data/lib/card/core_ext.rb CHANGED
@@ -28,24 +28,28 @@ class Object
28
28
  def send_if method, *args, &block
29
29
  ( block_given? ? yield : self ) and send method, *args
30
30
  end
31
-
31
+
32
32
  def to_name
33
33
  Card::Name.new self
34
34
  end
35
+
36
+ def to_viewname
37
+ Card::ViewName.new self
38
+ end
35
39
  end
36
40
 
37
41
 
38
42
 
39
43
  class Module
40
44
  RUBY_VERSION_18 = !!(RUBY_VERSION =~ /^1\.8/)
41
-
45
+
42
46
  def const_get_if_defined const
43
47
  args = RUBY_VERSION_18 ? [ const ] : [ const, false ]
44
48
  if const_defined? *args
45
49
  const_get *args
46
50
  end
47
51
  end
48
-
52
+
49
53
  def const_get_or_set const
50
54
  const_get_if_defined const or const_set const, yield
51
55
  end
@@ -79,13 +83,13 @@ class Kaminari::Helpers::Tag
79
83
  card = Card[p.delete('id')]
80
84
  card.format.path p
81
85
  end
82
-
86
+
83
87
  private
84
-
88
+
85
89
  def params_for(page)
86
90
  page_params = Rack::Utils.parse_nested_query("#{@param_name}=#{page}")
87
91
  page_params = @params.with_indifferent_access.deep_merge(page_params)
88
-
92
+
89
93
  if Kaminari.config.respond_to?(:params_on_first_page) && !Kaminari.config.params_on_first_page && page <= 1
90
94
  # This converts a hash:
91
95
  # from: {other: "params", page: 1}
@@ -97,7 +101,7 @@ class Kaminari::Helpers::Tag
97
101
  # (when @param_name == "user[page]")
98
102
  @param_name.to_s.scan(/\w+/)[0..-2].inject(page_params){|h, k| h[k] }[$&] = nil
99
103
  end
100
-
104
+
101
105
  page_params
102
106
  end
103
107
  end
data/lib/card/format.rb CHANGED
@@ -367,7 +367,7 @@ class Card
367
367
 
368
368
  def canonicalize_view view
369
369
  unless view.blank?
370
- view_key = view.to_name.key.to_sym
370
+ view_key = view.to_viewname.key.to_sym
371
371
  DEPRECATED_VIEWS[view_key] || view_key
372
372
  end
373
373
  end
data/lib/card/name.rb CHANGED
@@ -37,7 +37,7 @@ class Card
37
37
  name = trait_name( tag_code )
38
38
  name ? name.s : ( raise Card::NotFound, "unknown codename: #{tag_code}" )
39
39
  end
40
-
40
+
41
41
  def code
42
42
  Card::Codename[ Card.fetch_id self ]
43
43
  end
data/lib/card/set.rb CHANGED
@@ -4,11 +4,11 @@ class Card
4
4
  #remove_const :Set if const_defined?(:Set, false)
5
5
 
6
6
  module Set
7
-
7
+
8
8
  mattr_accessor :modules, :traits
9
9
  @@modules = { :base=>[], :base_format=>{}, :nonbase=>{}, :nonbase_format=>{} }
10
-
11
-
10
+
11
+
12
12
  =begin
13
13
  A "Set" is a group of cards to which "Rules" may be applied. Sets can be as specific as
14
14
  a single card, as general as all cards, or anywhere in between.
@@ -21,49 +21,49 @@ class Card
21
21
  "Code rules" can be defined in a "set file" within any "Mod" (short for both "module" and
22
22
  "modification"). In accordance with Wagn's "MoVE" architecture, there are two main kinds of
23
23
  code rules you can create in a set file: Views, and Events. Events are associated with the
24
- Card class, and Views are associated with a Format class. You can also use set files to
24
+ Card class, and Views are associated with a Format class. You can also use set files to
25
25
  add or override Card and/or Format methods directly. The majority of Card code is contained
26
26
  in these files.
27
-
27
+
28
28
  (FIXME - define mod, add generator)
29
29
 
30
30
  Whenever you fetch or instantiate a card, it will automatically include all the
31
- set modules defined in set files associated with sets of which it is a member. This
31
+ set modules defined in set files associated with sets of which it is a member. This
32
32
  entails both simple model methods and "events", which are special methods explored
33
33
  in greater detail below.
34
-
34
+
35
35
  For example, say you have a Plaintext card named "Philipp+address", and you have set files
36
36
  for the following sets:
37
-
37
+
38
38
  * all cards
39
39
  * all Plaintext cards
40
40
  * all cards ending in +address
41
-
41
+
42
42
  When you run this:
43
-
43
+
44
44
  mycard = Card.fetch 'Philipp+address'
45
-
45
+
46
46
  ...then mycard will include the set modules associated with each of those sets in the above
47
47
  order. (The order is determined by the set pattern; see lib/card/set_pattern.rb for more
48
48
  information about set_ptterns and mod/core/set/all/fetch.rb for more about fetching.)
49
49
 
50
50
  Similarly, whenever a Format object is instantiated for a card, it includes all views
51
- associated with BOTH (a) sets of which the card is a member and (b) the current format or
51
+ associated with BOTH (a) sets of which the card is a member and (b) the current format or
52
52
  its ancestors. More on defining views below.
53
53
 
54
-
54
+
55
55
  In order to have a set file associated with "all cards ending in +address", you could create
56
56
  a file in mywagn/mod/mymod/set/right/address.rb. The recommended mechanism for doing so
57
57
  is running `wagn generate set modname set_pattern set_anchor`. In the current example, this
58
- would translate to `wagn generate set mymod right address`. Note that both the set_pattern
58
+ would translate to `wagn generate set mymod right address`. Note that both the set_pattern
59
59
  and the set_anchor must correspond to the codename of a card in the database to function
60
- correctly but you can add arbitrary subdirectories to organize your code rules. The rule above
60
+ correctly but you can add arbitrary subdirectories to organize your code rules. The rule above
61
61
  for example could be saved in mywagn/mod/mymod/set/right/address/america/north/canada.rb.
62
62
 
63
-
63
+
64
64
  When a Card application loads, it uses these files to autogenerate a tmp_file that uses this set file to
65
65
  createa Card::Set::Right::Address module which itself is extended with Card::Set. A set file
66
- is "just ruby" but is generally quite concise because Card uses its file location to
66
+ is "just ruby" but is generally quite concise because Card uses its file location to
67
67
  autogenerate ruby module names and then uses Card::Set module to provide additional API.
68
68
 
69
69
 
@@ -85,9 +85,9 @@ class Card
85
85
  module Format
86
86
  mattr_accessor :views
87
87
  @@views = {}
88
-
88
+
89
89
  def view view, *args, &block
90
- view = view.to_name.key.to_sym
90
+ view = view.to_viewname.key.to_sym
91
91
  views[self] ||= {}
92
92
  view_block = views[self][view] = if block_given?
93
93
  Card::Format.extract_class_vars view, args[0]
@@ -97,7 +97,7 @@ class Card
97
97
  end
98
98
  define_method "_view_#{ view }", view_block
99
99
  end
100
-
100
+
101
101
  def alias_block view, args
102
102
  opts = Hash===args[0] ? args.shift : { :view => args.shift }
103
103
  opts[:mod] ||= self
@@ -106,10 +106,10 @@ class Card
106
106
  rescue
107
107
  raise "cannot find #{ opts[:view] } view in #{ opts[:mod] }; failed to alias #{view} in #{self}"
108
108
  end
109
-
109
+
110
110
  end
111
111
 
112
-
112
+
113
113
  def format *format_names, &block
114
114
  if format_names.empty?
115
115
  format_names = [:base]
@@ -120,7 +120,7 @@ class Card
120
120
  define_on_format f, &block
121
121
  end
122
122
  end
123
-
123
+
124
124
  def define_on_format format_name=:base, &block
125
125
  klass = Card::Format.format_class_name format_name # format class name, eg. HtmlFormat
126
126
  mod = const_get_or_set klass do # called on current set module, eg Card::Set::Type::Pointer
@@ -128,7 +128,7 @@ class Card
128
128
  register_set_format Card.const_get(klass), m
129
129
  m.extend Card::Set::Format
130
130
  m
131
- end
131
+ end
132
132
  mod.class_eval &block
133
133
  end
134
134
 
@@ -137,7 +137,7 @@ class Card
137
137
  view *args, &block
138
138
  end
139
139
  end
140
-
140
+
141
141
 
142
142
  def event event, opts={}, &final
143
143
  opts[:on] = [:create, :update ] if opts[:on] == :save
@@ -156,12 +156,12 @@ class Card
156
156
  end
157
157
  end
158
158
  end
159
-
159
+
160
160
  set_event_callbacks event, opts
161
161
  end
162
162
 
163
163
 
164
-
164
+
165
165
  #
166
166
  # ActiveCard support: accessing plus cards as attributes
167
167
  #
@@ -186,30 +186,30 @@ class Card
186
186
 
187
187
 
188
188
  # the set loading process has two main phases:
189
-
189
+
190
190
  # 1. Definition: interpret each set file, creating/defining set and set_format modules
191
191
  # 2. Organization: have base classes include modules associated with the "all" set, and
192
192
  # clean up the other modules
193
-
193
+
194
194
  class << self
195
195
 
196
196
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
197
197
  # Definition Phase
198
-
198
+
199
199
  # each set file calls `extend Card::Set` when loaded
200
200
  def extended mod
201
201
  register_set mod
202
202
  end
203
-
203
+
204
204
  def register_set set_module
205
205
  if set_module.all_set?
206
206
  modules[ :base ] << set_module
207
207
  else
208
208
  modules[ :nonbase ][ set_module.shortname ] ||= []
209
209
  modules[ :nonbase ][ set_module.shortname ] << set_module
210
- end
210
+ end
211
211
  end
212
-
212
+
213
213
  def write_tmp_file set_pattern, anchors, from_file, seq
214
214
  # FIXME - this does not properly handle anchorless sets
215
215
  # There are special hacks for *all, but others (like *rstar) will not be found by
@@ -233,8 +233,8 @@ EOF
233
233
  File.write to_file, file_content
234
234
  to_file
235
235
  end
236
-
237
-
236
+
237
+
238
238
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
239
239
  # Organization Phase
240
240
 
@@ -248,7 +248,7 @@ EOF
248
248
  modules.delete :base
249
249
  modules.delete :base_format
250
250
  end
251
-
251
+
252
252
  def process_base_module_list list, klass
253
253
  list.each do |mod|
254
254
  if mod.instance_methods.any?
@@ -259,21 +259,21 @@ EOF
259
259
  end
260
260
  end
261
261
  end
262
-
262
+
263
263
  def clean_empty_modules
264
264
  clean_empty_module_from_hash modules[ :nonbase ]
265
265
  modules[ :nonbase_format ].values.each do |hash|
266
266
  clean_empty_module_from_hash hash
267
267
  end
268
268
  end
269
-
269
+
270
270
  def clean_empty_module_from_hash hash
271
271
  hash.each do |mod_name, modlist|
272
272
  modlist.delete_if { |x| x.instance_methods.empty? }
273
273
  hash.delete mod_name if modlist.empty?
274
274
  end
275
275
  end
276
-
276
+
277
277
  end
278
278
 
279
279
 
@@ -292,7 +292,7 @@ EOF
292
292
  parts = name.split '::'
293
293
  first = 2 # shortname eliminates Card::Set
294
294
  set_class = Card::SetPattern.find parts[first].underscore
295
-
295
+
296
296
  last = first + set_class.anchor_parts_count
297
297
  parts[first..last].join '::'
298
298
  end
@@ -302,8 +302,8 @@ EOF
302
302
  end
303
303
 
304
304
  private
305
-
306
-
305
+
306
+
307
307
  def set_event_callbacks event, opts
308
308
  [:before, :after, :around].each do |kind|
309
309
  if object_method = opts.delete(kind)
@@ -326,11 +326,11 @@ EOF
326
326
  mod = self
327
327
  # raise "Can't define card traits on all set" if mod == Card
328
328
  mod_traits = get_traits mod
329
-
329
+
330
330
  new_opts = options[:type] ? {:type=>options[:type]} : {}
331
331
  new_opts.merge!( {:content => options[:default]} ) if options[:default]
332
-
333
- args.each do |trait|
332
+
333
+ args.each do |trait|
334
334
  define_trait_card trait, new_opts
335
335
  define_trait_reader trait if options[:reader]
336
336
  define_trait_writer trait if options[:writer]
@@ -338,7 +338,7 @@ EOF
338
338
  mod_traits[trait.to_sym] = options
339
339
  end
340
340
  end
341
-
341
+
342
342
  def define_trait_card trait, opts
343
343
  define_method "#{trait}_card" do
344
344
  trait_var "@#{trait}_card" do
@@ -346,7 +346,7 @@ EOF
346
346
  end
347
347
  end
348
348
  end
349
-
349
+
350
350
  def define_trait_reader trait
351
351
  define_method trait do
352
352
  trait_var "@#{trait}" do
@@ -6,7 +6,7 @@ def card_simplecov_filters
6
6
  # filter all card mods
7
7
  add_filter do |src_file|
8
8
  src_file.filename =~ /tmp\// and not
9
- /\d+-(.+\.rb)/.match(src_file.filename) { |m| Dir["mod/**/#{m[1]}"].present? }
9
+ /\d+-(.+\.rb)/.match(src_file.filename) { |m| Dir["mod/**/#{m[1].gsub("-","/")}"].present? }
10
10
  end
11
11
 
12
12
  # add group for each deck mod
@@ -15,7 +15,7 @@ def card_simplecov_filters
15
15
  src_file.filename =~ /mod\/#{mod}\// or
16
16
  (
17
17
  src_file.filename =~ /tmp\// and
18
- /\d+-(.+\.rb)/.match(src_file.filename) { |m| Dir["mod/#{mod}/**/#{m[1]}"].present? }
18
+ /\d+-(.+\.rb)/.match(src_file.filename) { |m| Dir["mod/#{mod}/**/#{m[1].gsub("-","/")}"].present? }
19
19
  )
20
20
  end
21
21
  end
@@ -4,7 +4,7 @@ module Card::SpecHelper
4
4
 
5
5
  include ActionDispatch::Assertions::SelectorAssertions
6
6
  #~~~~~~~~~ HELPER METHODS ~~~~~~~~~~~~~~~#
7
-
7
+
8
8
  def login_as user
9
9
  Card::Auth.current_id = (uc=Card[user.to_s] and uc.id)
10
10
  if @request
@@ -12,7 +12,7 @@ module Card::SpecHelper
12
12
  end
13
13
  #warn "(ath)login_as #{user.inspect}, #{Card::Auth.current_id}, #{@request.session[:user]}"
14
14
  end
15
-
15
+
16
16
  def newcard name, content=""
17
17
  #FIXME - misleading name; sounds like it doesn't save.
18
18
  Card.create! :name=>name, :content=>content
@@ -26,9 +26,19 @@ module Card::SpecHelper
26
26
  assert_select node, *args
27
27
  end
28
28
  end
29
-
29
+
30
30
  def debug_assert_view_select(view_html, *args, &block)
31
- Rails.logger.rspec "<pre>#{CGI.escapeHTML Nokogiri::XML(view_html,&:noblanks).to_s}</pre>"
31
+ Rails.logger.rspec %(
32
+ #{CodeRay.scan(Nokogiri::XML(view_html,&:noblanks).to_s, :html).div}
33
+ <style>
34
+ .CodeRay {
35
+ background-color: #FFF;
36
+ border: 1px solid #CCC;
37
+ padding: 1em 0px 1em 1em;
38
+ }
39
+ .CodeRay .code pre { overflow: auto }
40
+ </style>
41
+ )
32
42
  assert_view_select view_html, *args, &block
33
43
  end
34
44
 
@@ -40,7 +50,7 @@ module Card::SpecHelper
40
50
  def render_content content, format_args={}
41
51
  render_content_with_args( content, format_args )
42
52
  end
43
-
53
+
44
54
  def render_content_with_args content, format_args={}, view_args={}
45
55
  @card ||= Card.new :name=>"Tempo Rary 2"
46
56
  @card.content = content
@@ -50,7 +60,7 @@ module Card::SpecHelper
50
60
  def render_card view, card_args={}, format_args={}
51
61
  render_card_with_args view, card_args, format_args
52
62
  end
53
-
63
+
54
64
  def render_card_with_args view, card_args={}, format_args={}, view_args={}
55
65
  card = begin
56
66
  if card_args[:name]
@@ -61,7 +71,7 @@ module Card::SpecHelper
61
71
  end
62
72
  card.format(format_args)._render(view, view_args)
63
73
  end
64
-
74
+
65
75
  def users
66
76
  SharedData::USERS.sort
67
77
  end
@@ -0,0 +1,44 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require_dependency 'card/env'
3
+
4
+ require 'smart_name'
5
+
6
+ class Card
7
+ class ViewName < SmartName
8
+ @@name2viewnameobject = {}
9
+
10
+ class << self
11
+ def new obj
12
+ return obj if self.class===obj
13
+ str = Array===obj ? obj*joint : obj.to_s
14
+ if known_name = @@name2viewnameobject[str]
15
+ known_name
16
+ else
17
+ super str.strip
18
+ end
19
+ end
20
+ end
21
+
22
+ def initialize str
23
+ @s = str.to_s.strip
24
+ @s = @s.encode('UTF-8') if RUBYENCODING
25
+ @key = if @s.index(self.class.joint)
26
+ @parts = @s.split(/\s*#{JOINT_RE}\s*/)
27
+ @parts << '' if @s[-1,1] == self.class.joint
28
+ @simple = false
29
+ @parts.map { |p| p.to_name.key } * self.class.joint
30
+ else
31
+ @parts = [str]
32
+ @simple = true
33
+ str.empty? ? '' : simple_key
34
+ end
35
+ @@name2viewnameobject[str] = self
36
+ end
37
+
38
+ def simple_key
39
+ decoded.underscore.gsub(/[^#{OK4KEY_RE}]+/,'_').split(/_+/).reject(&:empty?)*'_'
40
+ end
41
+
42
+ def to_viewname() self end
43
+ end
44
+ end