card 1.18.3 → 1.18.4

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/card.gemspec +5 -3
  4. data/db/schema.rb +1 -1
  5. data/lib/card/active_record_helper.rb +2 -1
  6. data/lib/card/core_ext.rb +8 -0
  7. data/lib/card/format/nest.rb +13 -2
  8. data/lib/card/format/render.rb +7 -1
  9. data/lib/card/migration.rb +2 -1
  10. data/lib/card/set.rb +55 -70
  11. data/lib/card/set/trait.rb +70 -0
  12. data/lib/card/stage.rb +33 -8
  13. data/lib/card/stage_director.rb +3 -1
  14. data/lib/cardio.rb +2 -1
  15. data/mod/01_core/chunk/link.rb +7 -6
  16. data/mod/01_core/set/all/collection.rb +15 -52
  17. data/mod/01_core/set/all/fetch.rb +26 -6
  18. data/mod/01_core/set/all/references.rb +11 -3
  19. data/mod/01_core/set/all/subcards.rb +2 -2
  20. data/mod/01_core/set/all/tracked_attributes.rb +5 -1
  21. data/mod/01_core/set/all/utils.rb +1 -1
  22. data/mod/01_core/spec/set/all/collection_spec.rb +2 -2
  23. data/mod/01_history/set/all/content_history.rb +10 -11
  24. data/mod/02_basic_types/set/abstract/code_file.rb +57 -0
  25. data/mod/02_basic_types/set/type/pointer.rb +9 -5
  26. data/mod/03_machines/lib/javascript/wagn.js.coffee +4 -1
  27. data/mod/03_machines/lib/javascript/wagn_mod.js.coffee +29 -24
  28. data/mod/03_machines/set/self/script_ace.rb +1 -11
  29. data/mod/03_machines/set/self/script_card_menu.rb +1 -10
  30. data/mod/03_machines/set/self/script_html5shiv_printshiv.rb +1 -2
  31. data/mod/03_machines/set/self/script_jquery.rb +1 -2
  32. data/mod/03_machines/set/self/script_jquery_helper.rb +4 -7
  33. data/mod/03_machines/set/self/script_slot.rb +4 -6
  34. data/mod/03_machines/set/self/script_tinymce.rb +1 -2
  35. data/mod/03_machines/set/self/style_bootstrap_compatible.rb +1 -5
  36. data/mod/03_machines/set/self/style_cards.rb +1 -6
  37. data/mod/03_machines/set/self/style_jquery_ui_smoothness.rb +1 -2
  38. data/mod/03_machines/set/type/coffee_script.rb +1 -1
  39. data/mod/03_machines/set/type/css.rb +10 -1
  40. data/mod/03_machines/set/type/java_script.rb +16 -1
  41. data/mod/03_machines/set/type/scss.rb +3 -2
  42. data/mod/05_standard/lib/image_uploader.rb +15 -0
  43. data/mod/05_standard/set/all/rich_html/editing.rb +2 -2
  44. data/mod/05_standard/set/all/rich_html/form.rb +40 -19
  45. data/mod/05_standard/set/all/rich_html/modal.rb +4 -2
  46. data/mod/05_standard/set/all/rich_html/toolbar.rb +88 -39
  47. data/mod/05_standard/set/type/search_type.rb +6 -3
  48. data/mod/06_bootstrap/set/all/bootstrap/table.rb +55 -0
  49. data/mod/06_bootstrap/set/all/bootstrap/tabs.rb +81 -0
  50. data/mod/06_bootstrap/set/self/bootstrap_cards.rb +1 -9
  51. data/mod/06_bootstrap/set/self/bootstrap_js.rb +4 -6
  52. data/mod/06_bootstrap/set/self/bootswatch_shared.rb +11 -3
  53. data/mod/06_bootstrap/set/self/smartmenu_css.rb +3 -5
  54. data/mod/06_bootstrap/set/self/smartmenu_js.rb +3 -5
  55. data/spec/lib/card/set/trait_spec.rb +62 -0
  56. metadata +24 -3
@@ -1,11 +1 @@
1
-
2
- view :raw do |_args|
3
- Rails.logger.info "reading file: #{Cardio.gem_root}/mod/03_machines/lib/javascript/#{card.codename}.js"
4
- File.read "#{Cardio.gem_root}/mod/03_machines/lib/javascript/#{card.codename}.js"
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
1
+ include_set Abstract::CodeFile
@@ -1,10 +1 @@
1
- view :raw do |_args|
2
- Rails.logger.info "reading file: #{Cardio.gem_root}/mod/03_machines/lib/javascript/#{card.codename}.js.coffee"
3
- File.read "#{Cardio.gem_root}/mod/03_machines/lib/javascript/#{card.codename}.js.coffee"
4
- end
5
-
6
- format :html do
7
- view :editor do |_args|
8
- "Content is stored in file and can't be edited."
9
- end
10
- end
1
+ include_set Abstract::CodeFile
@@ -1,2 +1 @@
1
- format { include ScriptAce::Format }
2
- format(:html) { include ScriptAce::HtmlFormat }
1
+ include_set Abstract::CodeFile
@@ -1,2 +1 @@
1
- format { include ScriptAce::Format }
2
- format(:html) { include ScriptAce::HtmlFormat }
1
+ include_set Abstract::CodeFile
@@ -1,12 +1,9 @@
1
+ include_set Abstract::CodeFile
1
2
 
2
- view :raw do |_args|
3
+ def source_files
3
4
  # jquery.ui.all must be after jquery.mobile to override dialog weirdness *
4
5
  # jquery.ui.autocomplete must be after jquery.ui stuff
5
6
  # FIXME removed jquerymobile.js. Doesn't work with the new jquery version
6
- js_files = %w( jquery-ui.js jquery.ui.autocomplete.html.js jquery.autosize.js jquery.fileupload.js jquery.iframe-transport.js jquery_ujs.js )
7
- js_files.map do |filename|
8
- File.read "#{Cardio.gem_root}/mod/03_machines/lib/javascript/#{filename}"
9
- end.join("\n")
7
+ %w( jquery-ui.js jquery.ui.autocomplete.html.js jquery.autosize.js
8
+ jquery.fileupload.js jquery.iframe-transport.js jquery_ujs.js )
10
9
  end
11
-
12
- format(:html) { include ScriptAce::HtmlFormat }
@@ -1,7 +1,5 @@
1
- view :raw do |_args|
2
- ['wagn_mod.js.coffee', 'wagn.js.coffee'].map do |name|
3
- File.read "#{Cardio.gem_root}/mod/03_machines/lib/javascript/#{name}"
4
- end.join("\n")
5
- end
1
+ include_set Abstract::CodeFile
6
2
 
7
- format(:html) { include ScriptAce::HtmlFormat }
3
+ def source_files
4
+ %w( wagn_mod.js.coffee wagn.js.coffee )
5
+ end
@@ -1,2 +1 @@
1
- format { include ScriptAce::Format }
2
- format(:html) { include ScriptAce::HtmlFormat }
1
+ include_set Abstract::CodeFile
@@ -1,5 +1 @@
1
- view :raw do |_args|
2
- File.read "#{Cardio.gem_root}/mod/03_machines/lib/stylesheets/#{card.codename}.css"
3
- end
4
-
5
- format(:html) { include ScriptAce::HtmlFormat }
1
+ include_set Abstract::CodeFile
@@ -1,6 +1 @@
1
-
2
- view :raw do |_args|
3
- File.read "#{Cardio.gem_root}/mod/03_machines/lib/stylesheets/style_cards.scss"
4
- end
5
-
6
- format(:html) { include ScriptAce::HtmlFormat }
1
+ include_set Abstract::CodeFile
@@ -1,2 +1 @@
1
- format { include StyleBootstrapCompatible::Format }
2
- format(:html) { include ScriptAce::HtmlFormat }
1
+ include_set Abstract::CodeFile
@@ -11,7 +11,7 @@ include MachineInput
11
11
  def compile_coffee script
12
12
  ::CoffeeScript.compile script
13
13
  rescue => e
14
- e
14
+ raise Card::Error, "CoffeeScript::Error (#{name}): #{e.message}"
15
15
  end
16
16
 
17
17
  machine_input do
@@ -12,7 +12,16 @@ end
12
12
  def compress_css input
13
13
  Sass.compile input, style: :compressed
14
14
  rescue => e
15
- raise Card::Oops, "Stylesheet Error:\n#{e.message}"
15
+ # scss is compiled in a view
16
+ # If there is a scss syntax error we get the rescued view here
17
+ # and the error that the rescued view is no valid css
18
+ # To get the original error we have to refer to Card::Error.current
19
+ msg = if Card::Error.current
20
+ Card::Error.current.message
21
+ else
22
+ "Sass::SyntaxError (#{name}): #{e.message}"
23
+ end
24
+ raise Card::Error, msg
16
25
  end
17
26
 
18
27
  def clean_html?
@@ -7,7 +7,22 @@ include MachineInput
7
7
  store_machine_output filetype: 'js'
8
8
 
9
9
  machine_input do
10
- Uglifier.compile(format(:js)._render_core)
10
+ compress_js format(:js)._render_core
11
+ end
12
+
13
+ def compress_js input
14
+ Uglifier.compile(input)
15
+ rescue => e
16
+ # CoffeeScript is compiled in a view
17
+ # If there is a CoffeeScript syntax error we get the rescued view here
18
+ # and the error that the rescued view is no valid Javascript
19
+ # To get the original error we have to refer to Card::Error.current
20
+ msg = if Card::Error.current
21
+ Card::Error.current.message
22
+ else
23
+ "CoffeeScript::SyntaxError (#{name}): #{e.message}"
24
+ end
25
+ raise Card::Error, msg
11
26
  end
12
27
 
13
28
  def clean_html?
@@ -13,8 +13,9 @@ format do
13
13
 
14
14
  def compile_scss scss, style=:expanded
15
15
  Sass.compile scss, style: style
16
- rescue => e
17
- e
16
+ rescue Sass::SyntaxError => e
17
+ raise Card::Error, "Sass::SyntaxError (#{card.name}:#{e.sass_line}): " \
18
+ "#{e.message}"
18
19
  end
19
20
  end
20
21
 
@@ -20,6 +20,21 @@ class ImageUploader < FileUploader
20
20
  process resize_to_fit: [500, 500]
21
21
  end
22
22
 
23
+ # version :small_square, if: :create_versions?,
24
+ # from_version: :medium_square do
25
+ # process resize_to_fill: [75, 75]
26
+ # end
27
+ # version :medium_square, if: :create_versions? do
28
+ # process resize_to_fill: [200, 200]
29
+ # end
30
+ #
31
+ # In case we decide to support the squared versions
32
+ # we have to update all existing images with the following snippet:
33
+ # Card.search(type_id: Card::ImageID) do |card|
34
+ # card.image.cache_stored_file!
35
+ # card.image.recreate_versions!
36
+ # end
37
+
23
38
  def identifier
24
39
  full_filename(super())
25
40
  end
@@ -73,7 +73,7 @@ format :html do
73
73
  end
74
74
 
75
75
  view :edit, perms: :update, tags: :unknown_ok do |args|
76
- frame_and_form :update, args.merge(optional_toolbar: :show) do
76
+ frame_and_form :update, args.reverse_merge(optional_toolbar: :show) do
77
77
  [
78
78
  _optional_render(:content_formgroup, args),
79
79
  _optional_render(:button_formgroup, args)
@@ -214,7 +214,7 @@ format :html do
214
214
  view :edit_nests do |args|
215
215
  frame args do
216
216
  with_nest_mode :edit do
217
- process_relative_tags optional_toolbar: :hide
217
+ process_nested_fields optional_toolbar: :hide
218
218
  end
219
219
  end
220
220
  end
@@ -1,7 +1,8 @@
1
1
  format :html do
2
2
  def edit_slot args={}
3
3
  # note: @mode should already be :edit here...
4
- if args[:structure] || card.structure
4
+ if args[:structure] || card.structure ||
5
+ args[:edit_fields]
5
6
  multi_card_edit_slot args
6
7
  else
7
8
  single_card_edit_slot args
@@ -11,8 +12,10 @@ format :html do
11
12
  def multi_card_edit_slot args
12
13
  if args[:core_edit] # need better name
13
14
  _render_core args
15
+ elsif args[:edit_fields]
16
+ process_edit_fields args[:edit_fields]
14
17
  else
15
- process_relative_tags optional_toolbar: :hide,
18
+ process_nested_fields optional_toolbar: :hide,
16
19
  structure: args[:structure]
17
20
  end
18
21
  end
@@ -28,6 +31,28 @@ format :html do
28
31
  end
29
32
  end
30
33
 
34
+ def process_nested_fields args
35
+ nested_fields(args).map do |chunk|
36
+ nested_card = fetch_nested_card chunk.options
37
+ nest nested_card, chunk.options.reverse_merge(args)
38
+ end.join "\n"
39
+ end
40
+
41
+ # @param [Hash|Array] fields either an array with field names and/or field
42
+ # cards or a hash with the fields as keys and a hash with nest options as
43
+ # values
44
+ def process_edit_fields fields
45
+ fields.map do |field, opts|
46
+ nested_card =
47
+ if field.is_a?(Card)
48
+ field
49
+ else
50
+ fetch_nested_card inc_name: field
51
+ end
52
+ nest nested_card, opts
53
+ end.join "\n"
54
+ end
55
+
31
56
  def form_for_multi
32
57
  instantiate_builder("card#{subcard_input_names}", card, {})
33
58
  end
@@ -99,7 +124,7 @@ format :html do
99
124
  def formgroup title, content, opts={}
100
125
  wrap_with :div, formgroup_div_args(opts[:class]) do
101
126
  %(
102
- <label>#{title}</label>
127
+ #{form.label(opts[:editor] || :content, title)}
103
128
  <div>
104
129
  #{editor_wrap(opts[:editor]) { content }}
105
130
  #{formgroup_help_text opts[:help]}
@@ -127,12 +152,13 @@ format :html do
127
152
  result = ''
128
153
  hash ||= {}
129
154
  hash.each do |key, val|
130
- result += if Hash === val
131
- hidden_tags val, key
132
- else
133
- name = base ? "#{base}[#{key}]" : key
134
- hidden_field_tag name, val
135
- end
155
+ result +=
156
+ if val.is_a?(Hash)
157
+ hidden_tags val, key
158
+ else
159
+ name = base ? "#{base}[#{key}]" : key
160
+ hidden_field_tag name, val
161
+ end
136
162
  end
137
163
  result
138
164
  end
@@ -140,15 +166,17 @@ format :html do
140
166
  # FIELDSET VIEWS
141
167
 
142
168
  view :name_formgroup do |args|
143
- formgroup 'name', raw(name_field form), editor: 'name', help: args[:help]
169
+ formgroup 'name', raw(name_field(form)),
170
+ editor: 'name', help: args[:help]
144
171
  end
145
172
 
146
173
  view :type_formgroup do |args|
147
174
  field = if args[:variety] == :edit # FIXME: dislike this api -ef
148
175
  type_field class: 'type-field edit-type-field'
149
176
  else
150
- type_field class: 'type-field live-type-field', href: path(view: :new), 'data-remote' => true
151
- end
177
+ type_field class: 'type-field live-type-field',
178
+ href: path(view: :new), 'data-remote' => true
179
+ end
152
180
  formgroup 'type', field, editor: 'type', class: 'type-formgroup'
153
181
  end
154
182
 
@@ -224,13 +252,6 @@ format :html do
224
252
  formgroup fancy_title(args[:title]), content, opts
225
253
  end
226
254
 
227
- def process_relative_tags args
228
- nested_fields(args).map do |chunk|
229
- nested_card = fetch_nested_card chunk.options
230
- nest nested_card, chunk.options.reverse_merge(args)
231
- end.join "\n"
232
- end
233
-
234
255
  # form helpers
235
256
 
236
257
  FIELD_HELPERS =
@@ -8,10 +8,12 @@ format :html do
8
8
  link_to(args[:text] || _render_title(args), path(path_opts), html_args)
9
9
  end
10
10
 
11
- view :modal_slot do |args|
11
+ view :modal_slot, tags: :unknown_ok do |args|
12
12
  id = "modal-#{args[:modal_id] || 'main-slot'}"
13
+ dialog_args = { class: 'modal-dialog' }
14
+ add_class dialog_args, args[:dialog_class]
13
15
  wrap_with(:div, class: 'modal fade', role: 'dialog', id: id) do
14
- wrap_with(:div, class: 'modal-dialog') do
16
+ wrap_with(:div, dialog_args) do
15
17
  content_tag :div, class: 'modal-content' do
16
18
  ''
17
19
  end
@@ -1,12 +1,14 @@
1
-
2
1
  format :html do
3
2
  def toolbar_pinned?
4
3
  (tp = Card[:toolbar_pinned]) && tp.content == 'true'
5
4
  end
6
5
 
7
6
  view :toolbar do |args|
8
- navbar "toolbar-#{card.cardname.safe_key}-#{args[:home_view]}", toggle_align: :left, class: 'slotter toolbar', navbar_type: 'inverse',
9
- collapsed_content: close_link(args.merge(class: 'pull-right visible-xs')) do
7
+ collapsed = close_link(args.merge(class: 'pull-right visible-xs'))
8
+ navbar "toolbar-#{card.cardname.safe_key}-#{args[:home_view]}",
9
+ toggle_align: :left, class: 'slotter toolbar',
10
+ navbar_type: 'inverse',
11
+ collapsed_content: collapsed do
10
12
  [
11
13
  close_link(args.merge(class: 'hidden-xs navbar-right')),
12
14
  (wrap_with(:form, class: 'navbar-form navbar-left') do
@@ -25,6 +27,7 @@ format :html do
25
27
  ]
26
28
  end
27
29
  end
30
+
28
31
  def default_toolbar_args args
29
32
  args[:nested_fields] = nested_fields(args)
30
33
  args[:active_toolbar_button] ||= active_toolbar_button @slot_view, args
@@ -54,11 +57,18 @@ format :html do
54
57
  end
55
58
  end
56
59
 
60
+ TOOLBAR_TITLE = {
61
+ edit: 'content', edit_name: 'name', edit_type: 'type',
62
+ edit_structure: 'structure', edit_nests: 'nests', history: 'history',
63
+ common_rules: 'common', recent_rules: 'recent', grouped_rules: 'all',
64
+ edit_nest_rules: 'nests'
65
+ }.freeze
66
+
57
67
  def toolbar_view_title view
58
68
  if view == :edit_rules
59
69
  current_set_card.name
60
70
  else
61
- { edit: 'content', edit_name: 'name', edit_type: 'type', edit_structure: 'structure', edit_nests: 'nests', history: 'history', common_rules: 'common', recent_rules: 'recent', grouped_rules: 'all', edit_nest_rules: 'nests' }[view]
71
+ TOOLBAR_TITLE[view]
62
72
  end
63
73
  end
64
74
 
@@ -76,11 +86,16 @@ format :html do
76
86
  end
77
87
 
78
88
  def rules_split_button args
79
- recent = smart_link 'recent', view: :edit_rules, slot: { rule_view: :recent_rules }
80
- common = smart_link 'common', view: :edit_rules, slot: { rule_view: :common_rules }
81
- group = smart_link 'by group', view: :edit_rules, slot: { rule_view: :grouped_rules }
82
- all = smart_link 'by name', view: :edit_rules, slot: { rule_view: :all_rules }
83
- nests = smart_link 'nests', view: :edit_nest_rules, slot: { rule_view: :field_related_rules }
89
+ recent = smart_link 'recent', view: :edit_rules,
90
+ slot: { rule_view: :recent_rules }
91
+ common = smart_link 'common', view: :edit_rules,
92
+ slot: { rule_view: :common_rules }
93
+ group = smart_link 'by group', view: :edit_rules,
94
+ slot: { rule_view: :grouped_rules }
95
+ all = smart_link 'by name', view: :edit_rules,
96
+ slot: { rule_view: :all_rules }
97
+ nests = smart_link 'nests', view: :edit_nest_rules,
98
+ slot: { rule_view: :field_related_rules }
84
99
  toolbar_split_button 'rules', { view: :edit_rules }, args do
85
100
  {
86
101
  common_rules: common,
@@ -97,19 +112,27 @@ format :html do
97
112
  toolbar_split_button 'edit', { view: :edit }, args do
98
113
  {
99
114
  edit: _render_edit_content_link(args),
100
- edit_nests: (_render_edit_nests_link if !card.structure && args[:nested_fields].present?),
101
- structure: (smart_link 'structure', view: :edit_structure if structure_editable?),
115
+ edit_nests: (_render_edit_nests_link if nests_editable?(args)),
116
+ structure: (_render_edit_structure_link if structure_editable?),
102
117
  edit_name: _render_edit_name_link,
103
118
  edit_type: _render_edit_type_link
104
119
  }
105
120
  end
106
121
  end
107
122
 
123
+ def nests_editable? args
124
+ !card.structure && args[:nested_fields].present?
125
+ end
126
+
108
127
  def account_split_button args
109
128
  toolbar_split_button 'account', { related: Card[:account].key }, args do
110
129
  {
111
- account: smart_link('details', related: { name: "#{card.name}+#{Card[:account].key}", view: :edit }),
112
- roles: smart_link('roles', related: Card[:roles].key),
130
+ account: smart_link('details',
131
+ related: {
132
+ name: "#{card.name}+#{Card[:account].key}",
133
+ view: :edit }
134
+ ),
135
+ roles: smart_link('roles', related: Card[:roles].key),
113
136
  created: smart_link('created', related: Card[:created].key),
114
137
  edited: smart_link('edited', related: Card[:edited].key),
115
138
  follow: smart_link('follow', related: Card[:follow].key)
@@ -118,12 +141,15 @@ format :html do
118
141
  end
119
142
 
120
143
  def toolbar_split_button name, button_args, args
121
- button = button_link name, button_args, class: ('active' if args[:active_toolbar_button] == name)
144
+ button =
145
+ button_link name, button_args,
146
+ class: ('active' if args[:active_toolbar_button] == name)
122
147
  active_item =
123
148
  if @slot_view == :related
124
149
  if args[:rule_view]
125
150
  args[:rule_view].to_sym
126
- elsif args[:related_card] && (r = args[:related_card].right) && (cn = r.codename)
151
+ elsif args[:related_card] && (r = args[:related_card].right) &&
152
+ (cn = r.codename)
127
153
  cn.to_sym
128
154
  end
129
155
  else
@@ -135,10 +161,10 @@ format :html do
135
161
  end
136
162
 
137
163
  def close_link args
138
- link_opts = { title: 'cancel' }
164
+ link_opts = { title: 'cancel',
165
+ class: 'btn-toolbar-control btn btn-primary' }
139
166
  link_opts[:path_opts] = { slot: { subframe: true } } if args[:subslot]
140
-
141
- link = view_link glyphicon('remove'), :home, link_opts.merge(class: 'btn-toolbar-control btn btn-primary')
167
+ link = view_link glyphicon('remove'), :home, link_opts
142
168
  css_class = ['nav navbar-nav', args[:class]].compact.join "\n"
143
169
  wrap_with :div, class: css_class do
144
170
  [
@@ -146,17 +172,21 @@ format :html do
146
172
  link
147
173
  ]
148
174
  end
149
- # list_tag link, class: css_class
150
175
  end
151
176
 
152
177
  def toolbar_pin_button
153
- button_tag glyphicon('pushpin'), situation: :primary, remote: true, title: "#{'un' if toolbar_pinned?}pin", class: "btn-toolbar-control toolbar-pin #{'in' unless toolbar_pinned?}active"
178
+ button_tag glyphicon('pushpin'),
179
+ situation: :primary, remote: true,
180
+ title: "#{'un' if toolbar_pinned?}pin",
181
+ class: 'btn-toolbar-control toolbar-pin ' \
182
+ "#{'in' unless toolbar_pinned?}active"
154
183
  end
155
184
 
156
185
  view :toolbar_buttons do |args|
186
+ show_or_hide_delete = card.ok?(:delete) ? :show : :hide
157
187
  wrap_with(:div, class: 'btn-group') do
158
188
  [
159
- _optional_render(:delete_button, args, (card.ok?(:delete) ? :show : :hide)),
189
+ _optional_render(:delete_button, args, show_or_hide_delete),
160
190
  _optional_render(:refresh_button, args, :show),
161
191
  _optional_render(:related_button, args, :show),
162
192
  _optional_render(:history_button, args, :hide)
@@ -166,52 +196,63 @@ format :html do
166
196
 
167
197
  view :related_button do |_args|
168
198
  path_opts = { slot: { show: :toolbar } }
169
- dropdown_button '', icon: 'education', class: 'related' do # , icon: 'eye-open' do
199
+ dropdown_button '', icon: 'education', class: 'related' do
170
200
  [
171
- menu_item(' children', 'baby-formula', path_opts.merge(related: '*children')),
172
- menu_item(' mates', 'bed', path_opts.merge(related: '*mates')),
173
- menu_item(' references out', 'log-out', path_opts.merge(related: '*refers_to')),
174
- menu_item(' references in', 'log-in', path_opts.merge(related: '*referred_to_by'))
201
+ menu_item(' children', 'baby-formula',
202
+ path_opts.merge(related: '*children')),
203
+ menu_item(' mates', 'bed',
204
+ path_opts.merge(related: '*mates')),
205
+ menu_item(' references out', 'log-out',
206
+ path_opts.merge(related: '*refers_to')),
207
+ menu_item(' references in', 'log-in',
208
+ path_opts.merge(related: '*referred_to_by'))
175
209
  ]
176
210
  end
177
211
  end
178
212
  view :refresh_button do |_args|
179
213
  path_opts = { slot: { show: :toolbar }, page: card }
180
214
  icon = main? ? 'refresh' : 'new-window'
181
- toolbar_button('refresh', icon, 'hidden-xs hidden-sm hidden-md hidden-lg', path_opts: path_opts)
215
+ toolbar_button 'refresh', icon, 'hidden-xs hidden-sm hidden-md hidden-lg',
216
+ path_opts: path_opts
182
217
  end
183
218
 
184
219
  view :delete_button do |_args|
185
- toolbar_button('delete', 'trash', 'hidden-xs hidden-sm hidden-md hidden-lg',
186
- action: :delete,
187
- class: 'slotter',
188
- remote: true,
189
- path_opts: { success: main? ? 'REDIRECT: *previous' : "TEXT: #{card.name} deleted" },
190
- :'data-confirm' => "Are you sure you want to delete #{card.name}?"
191
- )
220
+ toolbar_button(
221
+ 'delete', 'trash', 'hidden-xs hidden-sm hidden-md hidden-lg',
222
+ action: :delete,
223
+ class: 'slotter',
224
+ remote: true,
225
+ path_opts: {
226
+ success: main? ? 'REDIRECT: *previous' : "TEXT: #{card.name} deleted"
227
+ },
228
+ :'data-confirm' => "Are you sure you want to delete #{card.name}?"
229
+ )
192
230
  end
193
231
 
194
232
  def toolbar_button text, symbol, hide=nil, tag_args={}
195
233
  hide ||= 'hidden-xs hidden-sm hidden-md hidden-lg'
196
234
  tag_args[:class] = [tag_args[:class], 'btn btn-primary'].compact * ' '
197
235
  tag_args[:title] ||= text
198
- link_text = "#{glyphicon symbol}<span class='menu-item-label #{hide}'>#{text}</span>"
236
+ link_text =
237
+ glyphicon(symbol) +
238
+ content_tag(:span, text.html_safe, class: "menu-item-label #{hide}")
199
239
 
200
- if cardname = tag_args.delete(:page)
240
+ if (cardname = tag_args.delete(:page))
201
241
  card_link cardname, class: klass, text: link_text
202
- elsif viewname = tag_args.delete(:view)
242
+ elsif (viewname = tag_args.delete(:view))
203
243
  tag_args[:path_opts] ||= { slot: { show: :toolbar } }
204
244
  view_link link_text, viewname, tag_args
205
245
  else
206
246
  path_opts = tag_args.delete(:path_opts) || {}
207
247
  path_opts[:action] = tag_args.delete(:action) if tag_args[:action]
208
248
  link_to link_text, path_opts, tag_args
209
-
210
249
  end
211
250
  end
212
251
 
213
252
  def autosaved_draft_link
214
- view_link('autosaved draft', :edit, path_opts: { edit_draft: true, slot: { show: :toolbar } }, class: 'navbar-link slotter pull-right')
253
+ view_link 'autosaved draft', :edit,
254
+ path_opts: { edit_draft: true, slot: { show: :toolbar } },
255
+ class: 'navbar-link slotter pull-right'
215
256
  end
216
257
 
217
258
  def default_edit_content_link_args args
@@ -220,24 +261,32 @@ format :html do
220
261
  view :edit_content_link do |args|
221
262
  toolbar_view_link :edit, args
222
263
  end
264
+
223
265
  def default_edit_name_link_args args
224
266
  args[:title] ||= 'name'
225
267
  end
226
268
  view :edit_name_link do |args|
227
269
  toolbar_view_link :edit_name, args
228
270
  end
271
+
229
272
  def default_edit_type_link_args args
230
273
  args[:title] ||= 'type'
231
274
  end
232
275
  view :edit_type_link do |args|
233
276
  toolbar_view_link :edit_type, args
234
277
  end
278
+
279
+ view :edit_structure_link do |_args|
280
+ smart_link 'structure', view: :edit_structure
281
+ end
282
+
235
283
  def default_history_link_args args
236
284
  args[:title] ||= 'history'
237
285
  end
238
286
  view :history_link do |args|
239
287
  toolbar_view_link :history, args
240
288
  end
289
+
241
290
  def default_edit_nests_link_args args
242
291
  args[:title] ||= 'nests'
243
292
  end