card 1.15.1 → 1.15.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (222) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/card.gemspec +19 -16
  4. data/config/initializers/recaptcha.rb +1 -0
  5. data/db/migrate_core_cards/20150202143810_import_bootstrap_layout.rb +13 -14
  6. data/db/migrate_core_cards/20150326205655_bootswatch_themes.rb +30 -0
  7. data/db/migrate_core_cards/20150331135745_new_card_menu.rb +8 -0
  8. data/db/migrate_core_cards/20150508212032_menu_compatibility.rb +27 -0
  9. data/db/migrate_core_cards/20150510031118_fix_skin_images.rb +13 -0
  10. data/db/migrate_core_cards/data/1.12_stylesheets/classic_cards.scss +9 -5
  11. data/db/migrate_core_cards/data/1.12_stylesheets/common.scss +5 -5
  12. data/{test/fixtures/.gitkeep → db/migrate_core_cards/data/themes/bootstrap_default/_bootswatch.scss} +0 -0
  13. data/db/migrate_core_cards/data/themes/bootstrap_default/_variables.scss +866 -0
  14. data/db/migrate_core_cards/data/themes/cerulean/_bootswatch.scss +125 -0
  15. data/db/migrate_core_cards/data/themes/cerulean/_variables.scss +861 -0
  16. data/db/migrate_core_cards/data/themes/cosmo/_bootswatch.scss +237 -0
  17. data/db/migrate_core_cards/data/themes/cosmo/_variables.scss +861 -0
  18. data/db/migrate_core_cards/data/themes/cyborg/_bootswatch.scss +210 -0
  19. data/db/migrate_core_cards/data/themes/cyborg/_variables.scss +861 -0
  20. data/db/migrate_core_cards/data/themes/darkly/_bootswatch.scss +330 -0
  21. data/db/migrate_core_cards/data/themes/darkly/_variables.scss +861 -0
  22. data/db/migrate_core_cards/data/themes/flatly/_bootswatch.scss +313 -0
  23. data/db/migrate_core_cards/data/themes/flatly/_variables.scss +861 -0
  24. data/db/migrate_core_cards/data/themes/journal/_bootswatch.scss +120 -0
  25. data/db/migrate_core_cards/data/themes/journal/_variables.scss +861 -0
  26. data/db/migrate_core_cards/data/themes/lumen/_bootswatch.scss +496 -0
  27. data/db/migrate_core_cards/data/themes/lumen/_variables.scss +861 -0
  28. data/db/migrate_core_cards/data/themes/paper/_bootswatch.scss +607 -0
  29. data/db/migrate_core_cards/data/themes/paper/_variables.scss +861 -0
  30. data/db/migrate_core_cards/data/themes/readable/_bootswatch.scss +174 -0
  31. data/db/migrate_core_cards/data/themes/readable/_variables.scss +861 -0
  32. data/db/migrate_core_cards/data/themes/sandstone/_bootswatch.scss +194 -0
  33. data/db/migrate_core_cards/data/themes/sandstone/_variables.scss +861 -0
  34. data/db/migrate_core_cards/data/themes/simplex/_bootswatch.scss +142 -0
  35. data/db/migrate_core_cards/data/themes/simplex/_variables.scss +861 -0
  36. data/db/migrate_core_cards/data/themes/slate/_bootswatch.scss +417 -0
  37. data/db/migrate_core_cards/data/themes/slate/_variables.scss +861 -0
  38. data/db/migrate_core_cards/data/themes/spacelab/_bootswatch.scss +137 -0
  39. data/db/migrate_core_cards/data/themes/spacelab/_variables.scss +861 -0
  40. data/db/migrate_core_cards/data/themes/superhero/_bootswatch.scss +332 -0
  41. data/db/migrate_core_cards/data/themes/superhero/_variables.scss +861 -0
  42. data/db/migrate_core_cards/data/themes/united/_bootswatch.scss +42 -0
  43. data/db/migrate_core_cards/data/themes/united/_variables.scss +861 -0
  44. data/db/migrate_core_cards/data/themes/yeti/_bootswatch.scss +437 -0
  45. data/db/migrate_core_cards/data/themes/yeti/_variables.scss +861 -0
  46. data/db/seed/README.md +2 -0
  47. data/db/{bootstrap → seed/new}/card_actions.yml +561 -295
  48. data/db/{bootstrap → seed/new}/card_acts.yml +1 -1
  49. data/db/seed/new/card_changes.yml +29331 -0
  50. data/db/{bootstrap → seed/new}/card_references.yml +1544 -1355
  51. data/db/seed/new/cards.yml +28057 -0
  52. data/db/seed/test/fixtures/.gitkeep +0 -0
  53. data/{test → db/seed/test}/fixtures/card_actions.yml +1501 -1235
  54. data/{test → db/seed/test}/fixtures/card_acts.yml +244 -244
  55. data/db/seed/test/fixtures/card_changes.yml +34527 -0
  56. data/{test → db/seed/test}/fixtures/card_references.yml +2215 -2026
  57. data/db/seed/test/fixtures/cards.yml +32708 -0
  58. data/{test → db/seed/test}/fixtures/mao2.jpg +0 -0
  59. data/{test → db/seed/test}/fixtures/rails.gif +0 -0
  60. data/{test → db/seed/test}/seed.rb +0 -0
  61. data/db/version_core_cards.txt +1 -1
  62. data/lib/card/format.rb +56 -56
  63. data/lib/cardio.rb +7 -5
  64. data/mod/01_core/chunk/include.rb +1 -1
  65. data/mod/01_core/set/all/fetch.rb +27 -27
  66. data/mod/01_core/set/all/rules.rb +53 -53
  67. data/mod/01_core/set/all/states.rb +5 -0
  68. data/mod/01_core/spec/format/html_format_spec.rb +6 -6
  69. data/mod/01_core/spec/set/all/rules2_spec.rb +6 -6
  70. data/mod/01_history/set/all/history.rb +4 -4
  71. data/mod/02_basic_types/set/all/rss.rb +10 -9
  72. data/mod/03_machines/lib/javascript/script_card_menu.js.coffee +20 -0
  73. data/mod/03_machines/lib/javascript/wagn.js.coffee +46 -34
  74. data/mod/03_machines/lib/javascript/wagn_mod.js.coffee +36 -148
  75. data/mod/03_machines/lib/stylesheets/style_bootstrap_compatible.css +10 -96
  76. data/mod/03_machines/lib/stylesheets/style_cards.scss +127 -87
  77. data/mod/03_machines/set/self/script_card_menu.rb +10 -2
  78. data/mod/05_email/set/all/follow.rb +38 -22
  79. data/mod/05_email/set/right/follow.rb +79 -1
  80. data/mod/05_email/set/type_plus_right/user/follow.rb +31 -31
  81. data/mod/05_email/spec/set/all/follow_spec.rb +37 -28
  82. data/mod/05_email/spec/set/right/followers_spec.rb +29 -29
  83. data/mod/05_standard/set/all/error.rb +17 -20
  84. data/mod/05_standard/set/all/links.rb +31 -18
  85. data/mod/05_standard/set/all/rich_html/content.rb +41 -18
  86. data/mod/05_standard/set/all/rich_html/editing.rb +21 -17
  87. data/mod/05_standard/set/all/rich_html/header.rb +13 -48
  88. data/mod/05_standard/set/all/rich_html/menu.rb +147 -0
  89. data/mod/05_standard/set/all/rich_html/modal.rb +54 -0
  90. data/mod/05_standard/set/all/rich_html/toolbar.rb +237 -0
  91. data/mod/05_standard/set/all/rich_html/wrapper.rb +43 -25
  92. data/mod/05_standard/set/right/account.rb +8 -7
  93. data/mod/05_standard/set/rstar/rules.rb +111 -84
  94. data/mod/05_standard/set/self/head.rb +15 -15
  95. data/mod/05_standard/set/type/set.rb +65 -34
  96. data/mod/05_standard/spec/set/all/attach_spec.rb +1 -1
  97. data/mod/05_standard/spec/set/all/rich_html/wrapper_spec.rb +13 -9
  98. data/mod/05_standard/spec/set/rstar/rules_spec.rb +1 -1
  99. data/mod/06_bootstrap/lib/javascript/bootstrap.js +108 -97
  100. data/mod/06_bootstrap/lib/javascript/smartmenu.js +94 -0
  101. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_alerts.scss +73 -0
  102. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_badges.scss +68 -0
  103. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_breadcrumbs.scss +26 -0
  104. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_button-groups.scss +243 -0
  105. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_buttons.scss +160 -0
  106. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_carousel.scss +269 -0
  107. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_close.scss +36 -0
  108. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_code.scss +69 -0
  109. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_component-animations.scss +37 -0
  110. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_dropdowns.scss +214 -0
  111. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_forms.scss +578 -0
  112. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_glyphicons.scss +305 -0
  113. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_grid.scss +84 -0
  114. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_input-groups.scss +166 -0
  115. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_jumbotron.scss +50 -0
  116. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_labels.scss +66 -0
  117. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_list-group.scss +124 -0
  118. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_media.scss +61 -0
  119. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_mixins.scss +39 -0
  120. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_modals.scss +150 -0
  121. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_navbar.scss +662 -0
  122. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_navs.scss +242 -0
  123. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_normalize.scss +427 -0
  124. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_pager.scss +54 -0
  125. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_pagination.scss +88 -0
  126. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_panels.scss +265 -0
  127. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_popovers.scss +135 -0
  128. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_print.scss +107 -0
  129. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_progress-bars.scss +87 -0
  130. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_responsive-embed.scss +35 -0
  131. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_responsive-utilities.scss +177 -0
  132. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_scaffolding.scss +162 -0
  133. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_tables.scss +234 -0
  134. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_theme.scss +273 -0
  135. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_thumbnails.scss +38 -0
  136. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_tooltip.scss +102 -0
  137. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_type.scss +298 -0
  138. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_utilities.scss +55 -0
  139. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_variables.scss +866 -0
  140. data/mod/06_bootstrap/lib/stylesheets/bootstrap/_wells.scss +29 -0
  141. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_alerts.scss +14 -0
  142. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_background-variant.scss +11 -0
  143. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_border-radius.scss +18 -0
  144. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_buttons.scss +52 -0
  145. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_center-block.scss +7 -0
  146. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_clearfix.scss +22 -0
  147. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_forms.scss +88 -0
  148. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_gradients.scss +58 -0
  149. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_grid-framework.scss +81 -0
  150. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_grid.scss +122 -0
  151. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_hide-text.scss +21 -0
  152. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_image.scss +33 -0
  153. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_labels.scss +12 -0
  154. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_list-group.scss +31 -0
  155. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_nav-divider.scss +10 -0
  156. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_nav-vertical-align.scss +9 -0
  157. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_opacity.scss +8 -0
  158. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_pagination.scss +23 -0
  159. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_panels.scss +24 -0
  160. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_progress-bar.scss +10 -0
  161. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_reset-filter.scss +8 -0
  162. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_resize.scss +6 -0
  163. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_responsive-visibility.scss +21 -0
  164. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_size.scss +10 -0
  165. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_tab-focus.scss +9 -0
  166. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_table-row.scss +28 -0
  167. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_text-emphasis.scss +11 -0
  168. data/mod/06_bootstrap/lib/stylesheets/bootstrap/mixins/_text-overflow.scss +8 -0
  169. data/mod/06_bootstrap/lib/stylesheets/{bootswatch_mixins.scss → bootstrap/mixins/_vendor-prefixes.scss} +1 -61
  170. data/mod/06_bootstrap/lib/stylesheets/bootstrap_cards.scss +20 -13
  171. data/mod/06_bootstrap/lib/stylesheets/smartmenu.css +433 -0
  172. data/mod/06_bootstrap/set/all/bootstrap/wrapper.rb +2 -2
  173. data/mod/06_bootstrap/set/all/rich_bootstrap.rb +58 -4
  174. data/mod/06_bootstrap/set/self/bootstrap_js.rb +1 -1
  175. data/mod/06_bootstrap/set/self/bootswatch_shared.rb +32 -0
  176. data/mod/06_bootstrap/set/self/smartmenu_css.rb +7 -0
  177. data/mod/06_bootstrap/set/self/smartmenu_js.rb +7 -0
  178. data/spec/spec_helper.rb +16 -16
  179. metadata +133 -93
  180. data/db/bootstrap/card_changes.yml +0 -12765
  181. data/db/bootstrap/cards.yml +0 -11567
  182. data/db/seeds.rb +0 -8
  183. data/mod/03_machines/lib/javascript/script_card_menu.js +0 -72
  184. data/mod/06_bootstrap/lib/stylesheets/bootstrap_css.css +0 -6565
  185. data/mod/06_bootstrap/lib/stylesheets/theme_bootstrap_default.css +0 -476
  186. data/mod/06_bootstrap/lib/stylesheets/theme_cerulean.css +0 -6721
  187. data/mod/06_bootstrap/lib/stylesheets/theme_cosmo.css +0 -5898
  188. data/mod/06_bootstrap/lib/stylesheets/theme_cyborg.css +0 -5876
  189. data/mod/06_bootstrap/lib/stylesheets/theme_darkly.css +0 -5986
  190. data/mod/06_bootstrap/lib/stylesheets/theme_flatly.css +0 -6830
  191. data/mod/06_bootstrap/lib/stylesheets/theme_journal.css +0 -6647
  192. data/mod/06_bootstrap/lib/stylesheets/theme_lumen.css +0 -6097
  193. data/mod/06_bootstrap/lib/stylesheets/theme_paper.css +0 -6647
  194. data/mod/06_bootstrap/lib/stylesheets/theme_readable.css +0 -5896
  195. data/mod/06_bootstrap/lib/stylesheets/theme_sandstone.css +0 -6733
  196. data/mod/06_bootstrap/lib/stylesheets/theme_simplex.css +0 -5886
  197. data/mod/06_bootstrap/lib/stylesheets/theme_slate.css +0 -7057
  198. data/mod/06_bootstrap/lib/stylesheets/theme_spacelab.css +0 -5935
  199. data/mod/06_bootstrap/lib/stylesheets/theme_superhero.css +0 -5964
  200. data/mod/06_bootstrap/lib/stylesheets/theme_united.css +0 -6588
  201. data/mod/06_bootstrap/lib/stylesheets/theme_yeti.css +0 -6088
  202. data/mod/06_bootstrap/set/self/bootstrap_css.rb +0 -9
  203. data/mod/06_bootstrap/set/self/bootswatch_mixins.rb +0 -9
  204. data/mod/06_bootstrap/set/self/theme_bootstrap_default.rb +0 -2
  205. data/mod/06_bootstrap/set/self/theme_cerulean.rb +0 -9
  206. data/mod/06_bootstrap/set/self/theme_cosmo.rb +0 -2
  207. data/mod/06_bootstrap/set/self/theme_cyborg.rb +0 -2
  208. data/mod/06_bootstrap/set/self/theme_darkly.rb +0 -2
  209. data/mod/06_bootstrap/set/self/theme_flatly.rb +0 -2
  210. data/mod/06_bootstrap/set/self/theme_journal.rb +0 -2
  211. data/mod/06_bootstrap/set/self/theme_lumen.rb +0 -2
  212. data/mod/06_bootstrap/set/self/theme_paper.rb +0 -2
  213. data/mod/06_bootstrap/set/self/theme_readable.rb +0 -2
  214. data/mod/06_bootstrap/set/self/theme_sandstone.rb +0 -2
  215. data/mod/06_bootstrap/set/self/theme_simplex.rb +0 -2
  216. data/mod/06_bootstrap/set/self/theme_slate.rb +0 -2
  217. data/mod/06_bootstrap/set/self/theme_spacelab.rb +0 -2
  218. data/mod/06_bootstrap/set/self/theme_superhero.rb +0 -2
  219. data/mod/06_bootstrap/set/self/theme_united.rb +0 -2
  220. data/mod/06_bootstrap/set/self/theme_yeti.rb +0 -2
  221. data/test/fixtures/card_changes.yml +0 -17961
  222. data/test/fixtures/cards.yml +0 -16218
@@ -1,3 +1,11 @@
1
+ view :raw do |args|
1
2
 
2
- format { include ScriptAce::Format }
3
- format(:html) { include ScriptAce::HtmlFormat }
3
+ Rails.logger.info "reading file: #{Cardio.gem_root}/mod/03_machines/lib/javascript/#{card.codename}.js.coffee"
4
+ File.read "#{Cardio.gem_root}/mod/03_machines/lib/javascript/#{card.codename}.js.coffee"
5
+ end
6
+
7
+ format :html do
8
+ view :editor do |args|
9
+ "Content is stored in file and can't be edited."
10
+ end
11
+ end
@@ -19,11 +19,10 @@ event :cache_expired_because_of_new_user_rule, :before=>:extend, :when=>proc { |
19
19
  end
20
20
 
21
21
  format do
22
-
22
+
23
23
  def follow_link_hash args
24
24
  toggle = args[:toggle] || ( card.followed? ? :off : :on )
25
25
  hash = { :class => "follow-toggle-#{toggle}" }
26
-
27
26
  case toggle
28
27
  when :off
29
28
  hash[:content] = '*never'
@@ -34,13 +33,14 @@ format do
34
33
  hash[:title] = "send emails about changes to #{card.follow_label}"
35
34
  hash[:verb] = 'follow'
36
35
  end
36
+ follow_rule_name = card.default_follow_set_card.follow_rule_name( Auth.current.name )
37
+ hash[:path] = path :name=>follow_rule_name, :action=>:update,
38
+ :success=>{ :view=>:modal_content },
39
+ :card=>{ :content=>"[[#{hash[:content]}]]" }
37
40
  hash
38
-
39
41
  end
40
-
41
-
42
- end
43
42
 
43
+ end
44
44
 
45
45
  format :json do
46
46
  view :follow_status do |args|
@@ -49,7 +49,7 @@ format :json do
49
49
  end
50
50
 
51
51
  format :html do
52
-
52
+
53
53
  view :follow_link, :tags=>:unknown_ok, :perms=>:none do |args|
54
54
  hash = follow_link_hash args
55
55
  text = %[<span class="follow-verb">#{hash[:verb]}</span> #{args[:label]}]
@@ -62,12 +62,28 @@ format :html do
62
62
  }
63
63
  link_to text, '', opts
64
64
  end
65
-
65
+
66
66
  def default_follow_link_args args
67
67
  args[:toggle] ||= card.followed? ? :off : :on
68
68
  args[:label] ||= card.follow_label
69
69
  end
70
-
70
+
71
+
72
+ view :follow_modal_link, :tags=>:unknown_ok, :perms=>:none do |args|
73
+ hash = follow_link_hash args
74
+ text = %[#{glyphicon 'flag'}<span class="follow-verb menu-item-label">#{hash[:verb]}</span>]
75
+ follow_rule_card = Card.fetch(card.default_follow_set_card.follow_rule_name( Auth.current.name ), :new=>{})
76
+ opts = ( args[:html_args] || {} ).clone
77
+ opts.merge!(
78
+ :title => hash[:title],
79
+ 'data-path' => hash[:path],
80
+ 'data-toggle' => 'modal',
81
+ 'data-target' => "#modal-#{card.cardname.safe_key}",
82
+ )
83
+ opts[:class] = "follow-link #{opts[:class]}"
84
+ link_to text, hash[:path], opts
85
+ end
86
+
71
87
  end
72
88
 
73
89
 
@@ -91,7 +107,7 @@ def follow_rule_card?
91
107
  end
92
108
 
93
109
  def follow_option?
94
- codename && FollowOption.codenames.include?(codename.to_sym)
110
+ codename && FollowOption.codenames.include?(codename.to_sym)
95
111
  end
96
112
 
97
113
  # used for the follow menu
@@ -111,7 +127,7 @@ def followed_by? user_id
111
127
  end
112
128
 
113
129
  def followed?
114
- followed_by? Auth.current_id
130
+ followed_by? Auth.current_id
115
131
  end
116
132
 
117
133
 
@@ -119,9 +135,9 @@ def follow_rule_applies? follower_id
119
135
  follow_rule = rule :follow, :user_id=>follower_id
120
136
  if follow_rule.present?
121
137
  follow_rule.split("\n").each do |value|
122
-
138
+
123
139
  value_code = value.to_name.code
124
- accounted_ids = (
140
+ accounted_ids = (
125
141
  @follower_candidate_ids[ value_code ] ||=
126
142
  if block = FollowOption.follower_candidate_ids[ value_code ]
127
143
  block.call self
@@ -129,17 +145,17 @@ def follow_rule_applies? follower_id
129
145
  []
130
146
  end
131
147
  )
132
-
133
- applicable =
148
+
149
+ applicable =
134
150
  if test = FollowOption.test[ value_code ]
135
151
  test.call follower_id, accounted_ids
136
152
  else
137
153
  accounted_ids.include? follower_id
138
154
  end
139
-
155
+
140
156
  return value.gsub( /[\[\]]/, '' ) if applicable
141
157
  end
142
- end
158
+ end
143
159
  return false
144
160
  end
145
161
 
@@ -157,7 +173,7 @@ def default_follow_set_card
157
173
  end
158
174
 
159
175
 
160
- # returns true if according to the follow_field_rule followers of self also
176
+ # returns true if according to the follow_field_rule followers of self also
161
177
  # follow changes of field_card
162
178
  def followed_field? field_card
163
179
  (follow_field_rule = rule_card(:follow_fields)) || follow_field_rule.item_names.find do |item|
@@ -192,7 +208,7 @@ end
192
208
  def direct_follower_ids args={}
193
209
  result = ::Set.new
194
210
  with_follower_candidate_ids do
195
- set_names.each do |set_name|
211
+ set_names.each do |set_name|
196
212
  set_card = Card.fetch(set_name)
197
213
  set_card.all_user_ids_with_rule_for(:follow).each do |user_id|
198
214
  if (!result.include? user_id) and self.follow_rule_applies?(user_id)
@@ -205,9 +221,9 @@ def direct_follower_ids args={}
205
221
  end
206
222
 
207
223
  def all_direct_follower_ids_with_reason
208
- with_follower_candidate_ids do
224
+ with_follower_candidate_ids do
209
225
  visited = ::Set.new
210
- set_names.each do |set_name|
226
+ set_names.each do |set_name|
211
227
  set_card = Card.fetch(set_name)
212
228
  set_card.all_user_ids_with_rule_for(:follow).each do |user_id|
213
229
  if (!visited.include?(user_id)) && (follow_option = self.follow_rule_applies?(user_id))
@@ -243,7 +259,7 @@ module ClassMethods
243
259
  def follower_ids_cache
244
260
  Card.cache.read(FOLLOWER_IDS_CACHE_KEY) || {}
245
261
  end
246
-
262
+
247
263
  def write_follower_ids_cache hash
248
264
  Card.cache.write FOLLOWER_IDS_CACHE_KEY, hash
249
265
  end
@@ -1,9 +1,87 @@
1
1
  include All::Permissions::Follow
2
2
 
3
- def options
3
+ def options
4
4
  Card::FollowOption.cards.compact
5
5
  end
6
6
 
7
7
  def options_card
8
8
  Card.new :name=>'follow_options_card', :type_code=>:pointer, :content=>options.map {|oc| "[[#{oc.title}]]" }.join("\n")
9
9
  end
10
+
11
+
12
+ format :html do
13
+ def default_follow_item_args args
14
+ args[:condition] ||= Env.params[:condition] || '*always'
15
+ end
16
+
17
+ view :follow_item, :tags=>:unknown_ok do |args|
18
+ if card.new_card? || !card.include_item?(args[:condition])
19
+ button_view = :add_follow_rule_button
20
+ form_opts = {:add_item=>args[:condition]}
21
+ else
22
+ button_view = :delete_follow_rule_button
23
+ form_opts = {:drop_item=>args[:condition]}
24
+ end
25
+
26
+ text = if (option_card = Card.fetch args[:condition])
27
+ option_card.description(card.rule_set)
28
+ else
29
+ card.rule_set.follow_label
30
+ end
31
+ link_target = if card.rule_set.tag.codename == 'self'
32
+ card.rule_set_name.left
33
+ else
34
+ "#{card.rule_set_name}+by name"
35
+ end
36
+ wrap do
37
+ card_form({:action=>:update, :name=>card.name, :success=>{:view=>:follow_item}},
38
+ :hidden=>{:condition=>args[:condition]}.merge(form_opts)) do
39
+ output [
40
+ _optional_render(button_view, args),
41
+ card_link( link_target, :text=>text)
42
+ ]
43
+ end
44
+ end
45
+ end
46
+
47
+ def default_modal_content_args args
48
+ args[:card_key] ||= card.set_prototype.key
49
+ end
50
+
51
+ view :modal_header do |args|
52
+ %{
53
+ #{ link_to '&times;', '', 'aria-hidden'=>true, :class=>'close update-follow-link', 'data-dismiss'=>'modal', 'data-card_key'=>args[:card_key] }
54
+ <h4 class="modal-title">Get notified about changes</h4>
55
+ }
56
+ end
57
+
58
+ view :modal_body do |args|
59
+ wrap_with :ul, :class=>'delete-list list-group' do
60
+ card.item_names.map do |option|
61
+ content_tag :li, :class=>'list-group-item' do
62
+ subformat(card).render_follow_item :condition=>(option == '*never' ? '*always' : option)
63
+ end
64
+ end.join "\n"
65
+ end
66
+ end
67
+
68
+
69
+ view :modal_footer do |args|
70
+ card_link(args[:card_key], :text=>'more options', :path_opts=>{:view=>:related, :related=>{:name=>card.name,:view=>:related_edit_rule}}, :class=>'btn update-follow-link', 'data-card_key'=>args[:card_key]) +
71
+ link_to('Close', '', :class=>'btn btn-default update-follow-link', 'data-dismiss'=>'modal', 'data-card_key'=>args[:card_key])
72
+ end
73
+
74
+ view :delete_follow_rule_button do |args|
75
+ button_tag :type=>:submit, :class=>'btn-xs btn-item-delete btn-primary', 'aria-label'=>'Left Align' do
76
+ tag :span, :class=>"glyphicon glyphicon-ok", 'aria-hidden'=>"true"
77
+ end
78
+
79
+ end
80
+
81
+ view :add_follow_rule_button do |args|
82
+ button_tag :type=>:submit, :class=>'btn-xs btn-item-add', 'aria-label'=>'Left Align' do
83
+ tag :span, :class=>"glyphicon glyphicon-plus", 'aria-hidden'=>"true"
84
+ end
85
+ end
86
+
87
+ end
@@ -19,7 +19,7 @@ def virtual?; true end
19
19
 
20
20
  format() { include Card::Set::Type::Pointer::Format }
21
21
 
22
-
22
+
23
23
  format :html do
24
24
  include Card::Set::Type::Pointer::HtmlFormat
25
25
 
@@ -27,8 +27,8 @@ format :html do
27
27
  view :closed_content do |args|
28
28
  ''
29
29
  end
30
-
31
-
30
+
31
+
32
32
  view :core do |args|
33
33
  %{
34
34
  <div role="tabpanel">
@@ -44,8 +44,8 @@ format :html do
44
44
  </div>
45
45
  }
46
46
  end
47
-
48
-
47
+
48
+
49
49
  def followed_by_option
50
50
  hash = Hash.new { |h,k| h[k] = [] }
51
51
  card.item_cards.each do |follow_rule|
@@ -54,11 +54,11 @@ format :html do
54
54
  end
55
55
  end
56
56
  end
57
-
57
+
58
58
  def each_suggestion
59
59
  if (suggestions = Card["follow suggestions"])
60
60
  suggestions.item_names.each do |sug|
61
- if ((set_card = Card.fetch sug.to_name.left) && set_card.type_code == :set)
61
+ if ((set_card = Card.fetch sug.to_name.left) && set_card.type_code == :set)
62
62
  option_card = Card.fetch(sug.to_name.right) || Card[sug.to_name.right.to_sym]
63
63
  option = if option_card.follow_option?
64
64
  option_card.name
@@ -66,13 +66,13 @@ format :html do
66
66
  '*always'
67
67
  end
68
68
  yield(set_card, option)
69
- elsif ((set_card = Card.fetch sug) && set_card.type_code == :set)
69
+ elsif ((set_card = Card.fetch sug) && set_card.type_code == :set)
70
70
  yield(set_card, '*always')
71
71
  end
72
72
  end
73
73
  end
74
74
  end
75
-
75
+
76
76
  # returns hashes with existing and suggested follow options
77
77
  # structure:
78
78
  # set_pattern_class => [ {:card=>rule_card, :options=>['*always', '*created'] },.... ]
@@ -83,8 +83,8 @@ format :html do
83
83
  options = follow_rule.item_names.reject { |item| item == never}
84
84
  res[follow_rule.rule_set.subclass_for_set] << { :card=>follow_rule, :options=>options }
85
85
  end
86
-
87
- if Auth.signed_in? && Auth.current_id == card.left.id
86
+
87
+ if Auth.signed_in? && Auth.current_id == card.left.id
88
88
  each_suggestion do |set_card, option|
89
89
  suggested_rule_name = set_card.follow_rule_name(card.trunk)
90
90
  if (rule = res[set_card.subclass_for_set].find { |rule| rule[:card].name == suggested_rule_name })
@@ -94,39 +94,39 @@ format :html do
94
94
  else
95
95
  rule_card = Card.new(:name=>suggested_rule_name)
96
96
  res[set_card.subclass_for_set] << {:card=>rule_card, :options=>[option]}
97
- end
97
+ end
98
98
  end
99
99
  end
100
100
  res
101
101
  end
102
-
103
-
102
+
103
+
104
104
  view :following_list do |args|
105
- if !Auth.signed_in? || Auth.current_id != card.left.id
106
- hide_buttons = [:delete_button, :add_button]
105
+ if !Auth.signed_in? || Auth.current_id != card.left.id
106
+ hide_buttons = [:delete_follow_rule_button, :add_follow_rule_button]
107
107
  end
108
-
108
+
109
109
  sets = followed_by_set
110
110
  wrap_with :div, :class=>'pointer-list-editor' do
111
- wrap_with :ul, :class=>'delete-list list-group' do
112
-
111
+ wrap_with :ul, :class=>'delete-list list-group' do
112
+
113
113
  Card.set_patterns.select{|p| sets[p]}.reverse.map do |set_pattern|
114
114
  sets[set_pattern].map do |rule|
115
115
  rule[:options].map do |option|
116
-
116
+
117
117
  content_tag :li, :class=>'list-group-item' do
118
118
  subformat(rule[:card]).render_follow_item :condition=>option, :hide=>hide_buttons
119
119
  end
120
-
120
+
121
121
  end.join("\n")
122
122
  end.join("\n")
123
123
  end.join("\n")
124
-
124
+
125
125
  end
126
126
  end
127
127
  end
128
-
129
-
128
+
129
+
130
130
  view :ignoring_list do |args|
131
131
  ignore_list = []
132
132
  card.item_cards.each do |follow_rule|
@@ -137,32 +137,32 @@ format :html do
137
137
  end
138
138
  end
139
139
  if !Auth.signed_in? || Auth.current_id != card.left.id
140
- hide_buttons = [:delete_button, :add_button]
140
+ hide_buttons = [:delete_follow_rule_button, :add_follow_rule_button]
141
141
  end
142
142
  never = Card[:never].name
143
143
  wrap_with :div, :class=>'pointer-list-editor' do
144
144
  wrap_with :ul, :class=>'delete-list list-group' do
145
-
145
+
146
146
  ignore_list.map do |rule_card|
147
147
  content_tag :li, :class=>'list-group-item' do
148
148
  subformat(rule_card).render_follow_item :condition=>never, :hide=>hide_buttons
149
149
  end
150
150
  end.join "\n"
151
-
151
+
152
152
  end
153
153
  end
154
154
  end
155
-
155
+
156
156
  view :pointer_items, :tags=>:unknown_ok do |args|
157
157
  super(args.merge(:item=>:link))
158
158
  end
159
-
159
+
160
160
  view :errors, :perms=>:none do |args|
161
161
  if card.errors.any?
162
162
  if card.errors.find { |attrib,msg| attrib == :permission_denied }
163
163
  save_interrupted_action(request.env['REQUEST_URI'])
164
164
  title = "Problems with #{card.name}"
165
- frame args.merge(:slot_class=>"panel panel-warning", :title=>title, :hide=>'menu' ) do
165
+ frame args.merge(:panel_class=>"panel panel-warning", :title=>title, :hide=>'menu' ) do
166
166
  "You have to #{ link_to 'sign in', card_url(':signin') }" #" #{to_task}"
167
167
  end
168
168
  else
@@ -170,7 +170,7 @@ format :html do
170
170
  end
171
171
  end
172
172
  end
173
-
173
+
174
174
  end
175
175
 
176
176
  format(:css ) { include Card::Set::Type::Pointer::CssFormat }
@@ -4,9 +4,12 @@ describe "Card::Set::All::Follow" do
4
4
  def follow_view card_name
5
5
  render_card :follow_link, :name=>card_name
6
6
  end
7
-
7
+ def follow_modal_view card_name
8
+ render_card :follow_modal_link, :name=>card_name
9
+ end
10
+
8
11
  describe "follower_ids" do
9
-
12
+
10
13
  context 'when a new +*follow rule created' do
11
14
  it 'contains id of a new follower' do
12
15
  Card::Auth.as_bot do
@@ -15,35 +18,35 @@ describe "Card::Set::All::Follow" do
15
18
  end
16
19
  end
17
20
  end
18
-
19
-
21
+
22
+
20
23
  subject { Card[cardname].follower_names.sort }
21
24
  context 'followers of No One Sees Me' do
22
25
  let(:cardname) {'No One Sees Me'}
23
26
  it { is_expected.to eq([]) }
24
27
  end
25
-
28
+
26
29
  context 'followers of Magnifier' do
27
- let(:cardname) {'Magnifier'}
30
+ let(:cardname) {'Magnifier'}
28
31
  it { is_expected.to eq([])}
29
32
  end
30
-
33
+
31
34
  context 'followers of Magnifier+lens' do
32
- let(:cardname) {'Magnifier+lens'}
35
+ let(:cardname) {'Magnifier+lens'}
33
36
  it { is_expected.to eq ['Big Brother','Narcissist']}
34
37
  end
35
-
38
+
36
39
  context 'followers of Sunglasses' do
37
- let(:cardname) {'Sunglasses'}
40
+ let(:cardname) {'Sunglasses'}
38
41
  it { is_expected.to eq ['Big Brother', 'Narcissist', 'Optic fan', 'Sara', 'Sunglasses fan']}
39
42
  end
40
43
  context 'followers of Sunglasses+tint' do
41
- let(:cardname) {'Sunglasses+tint'}
44
+ let(:cardname) {'Sunglasses+tint'}
42
45
  it { is_expected.to eq ['Big Brother', 'Narcissist', 'Optic fan', 'Sara', 'Sunglasses fan']}
43
46
  end
44
-
47
+
45
48
  context 'followers of Google glass' do
46
- let(:cardname) {'Google glass'}
49
+ let(:cardname) {'Google glass'}
47
50
  it { is_expected.to eq ['Big Brother', 'Optic fan', 'Sara']}
48
51
  end
49
52
  end
@@ -51,34 +54,40 @@ describe "Card::Set::All::Follow" do
51
54
 
52
55
 
53
56
 
54
-
55
- describe "view: follow" do
57
+
58
+ describe "view: follow_link" do
56
59
  before do
57
60
  Card::Auth.current_id = Card['Big Brother'].id
58
61
  end
59
-
62
+
60
63
  def assert_following_view name, args
61
64
  assert_follow_view name, args.reverse_merge(:following => true, :text=>"unfollow #{name}")
62
65
  end
63
-
66
+
64
67
  # href="/card/update/Home+*self+philipp+*follow?card%5Bcontent%5D=%5B%5Bnever%5D%5D&success%5Bid%5D=Home&success%5Bview%5D=follow"
65
68
  def assert_follow_view name, args
66
69
  args[:user] ||= "Big_Brother"
67
70
  # href = "/card/update/#{args[:add_set].to_name.url_key}+#{args[:user]}+*follow?"
68
71
  # href += CGI.escape("card[content]") + '='
69
- # href +=
70
- # if args[:following]
72
+ # href +=
73
+ # if args[:following]
71
74
  # link_class = "follow-toggle-off"
72
75
  # CGI.escape("[[*never]]")
73
76
  # else
74
77
  # link_class = "follow-toggle-on"
75
78
  # CGI.escape("[[*always]]")
76
79
  # end
80
+
77
81
  link_class = args[:following] ? "follow-toggle-off" : "follow-toggle-on"
78
82
  assert_view_select follow_view(name), "a[class~=#{link_class}][href*='']", args[:text] || "follow #{name}"
79
83
  end
80
84
 
81
-
85
+ def assert_follow_modal_view card_name
86
+ href_part = args[:following] ? "never" : "always"
87
+ assert_view_select follow_view(name), "a[class~=follow-link][href*=#{href_part}]", args[:text] || "follow #{name}"
88
+ end
89
+
90
+
82
91
  context "when not following" do
83
92
  it 'renders follow link' do
84
93
  assert_follow_view 'No One Sees Me', :add_set=>'No One Sees Me+*self'
@@ -90,38 +99,38 @@ describe "Card::Set::All::Follow" do
90
99
  assert_following_view 'Look At Me', :add_set=>'Look at me+*self'
91
100
  end
92
101
  end
93
-
102
+
94
103
  context "when following *type" do
95
104
  it 'renders following link' do
96
105
  assert_following_view 'Sunglasses', :add_set=>'Sunglasses+*self'
97
106
  end
98
107
  end
99
-
108
+
100
109
  context "when following cardtype card" do
101
110
  it 'renders following all link' do
102
111
  assert_following_view 'Optic', :add_set=>'Optic+*type', :text=>'unfollow all "Optics"'
103
112
  end
104
113
  end
105
-
114
+
106
115
  context "when not following cardtype card" do
107
116
  it "renders 'follow all' link" do
108
117
  assert_follow_view 'Basic', :add_set=>'Basic+*type', :text=>'follow all "Basics"'
109
118
  end
110
119
  end
111
-
120
+
112
121
  context "when following *right" do
113
122
  it "renders following link" do
114
123
  assert_following_view 'Magnifier+lens', :add_set=>'Magnifier+lens+*self'
115
124
  end
116
125
  end
117
-
126
+
118
127
  context 'when following content I created' do
119
128
  before { Card::Auth.current_id = Card['Narcissist'].id }
120
129
  it "renders following link" do
121
130
  assert_following_view 'Sunglasses', :add_set=>'Sunglasses+*self', :user=>'Narcissist'
122
131
  end
123
132
  end
124
-
133
+
125
134
  context 'when following content I edited' do
126
135
  before { Card::Auth.current_id = Card['Narcissist'].id }
127
136
  it "renders following link" do
@@ -129,5 +138,5 @@ describe "Card::Set::All::Follow" do
129
138
  end
130
139
  end
131
140
  end
132
-
133
- end
141
+
142
+ end