card 1.18.3 → 1.18.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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