sibu 0.9.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/sibu/sibu.js.erb +17 -3
  3. data/app/assets/javascripts/tabs/van11y-accessible-tab-panel-aria.js +122 -124
  4. data/app/assets/stylesheets/sibu/defaults.scss +72 -80
  5. data/app/assets/stylesheets/sibu/sibu.css +8 -0
  6. data/app/controllers/sibu/application_controller.rb +8 -0
  7. data/app/controllers/sibu/pages_controller.rb +4 -3
  8. data/app/controllers/sibu/sites_controller.rb +1 -0
  9. data/app/helpers/sibu/pages_helper.rb +70 -21
  10. data/app/models/sibu/page.rb +0 -1
  11. data/app/models/sibu/site.rb +7 -0
  12. data/app/models/sibu/site_template.rb +1 -1
  13. data/app/views/layouts/sibu/edit_content.html.erb +176 -119
  14. data/app/views/sibu/images/edit.js.erb +5 -3
  15. data/app/views/sibu/pages/_code_edit_panel.html.erb +2 -2
  16. data/app/views/sibu/pages/_link_edit_panel.html.erb +6 -6
  17. data/app/views/sibu/pages/_map_edit_panel.html.erb +2 -2
  18. data/app/views/sibu/pages/_media_edit_panel.html.erb +6 -6
  19. data/app/views/sibu/pages/_new_section_panel.html.erb +1 -1
  20. data/app/views/sibu/pages/_paragraph_edit_panel.html.erb +2 -2
  21. data/app/views/sibu/pages/_text_edit_panel.html.erb +2 -2
  22. data/app/views/sibu/pages/child_element.js.erb +2 -2
  23. data/app/views/sibu/pages/clone_element.js.erb +2 -2
  24. data/app/views/sibu/pages/create_section.js.erb +1 -1
  25. data/app/views/sibu/pages/delete_element.js.erb +1 -1
  26. data/app/views/sibu/pages/delete_section.js.erb +1 -1
  27. data/app/views/sibu/pages/edit_element.js.erb +68 -66
  28. data/app/views/sibu/pages/edit_section.js.erb +6 -5
  29. data/app/views/sibu/pages/index.html.erb +1 -1
  30. data/app/views/sibu/pages/new_section.js.erb +22 -13
  31. data/app/views/sibu/pages/update_element.js.erb +2 -2
  32. data/app/views/sibu/pages/update_section.js.erb +3 -3
  33. data/config/initializers/constants.rb +5 -3
  34. data/db/migrate/20200401130601_add_ref_to_site_templates.rb +5 -0
  35. data/lib/sibu/engine.rb +0 -2
  36. data/lib/sibu/version.rb +1 -1
  37. metadata +3 -18
  38. data/app/views/sibu/pages/destroy.html.erb +0 -2
  39. data/app/views/sibu/pages/update.html.erb +0 -2
@@ -63,6 +63,10 @@
63
63
  background-color: white;
64
64
  }
65
65
 
66
+ #edit_panel.active, #sections_panel.active {
67
+ display: block;
68
+ }
69
+
66
70
  #element_actions button {
67
71
  display: none;
68
72
  }
@@ -78,6 +82,10 @@
78
82
  cursor: pointer;
79
83
  }
80
84
 
85
+ #edit_overlays > *:hover {
86
+ opacity: 1;
87
+ }
88
+
81
89
  .sb-editing [data-type] {
82
90
  min-width: 1em;
83
91
  min-height: 0.5em;
@@ -10,5 +10,13 @@ module Sibu
10
10
  def sibu_user
11
11
  send(conf[:current_user])
12
12
  end
13
+
14
+ def check_site_ownership!
15
+ if conf[:multi_user] && conf[:admin_filter]
16
+ unless @site.nil? || @site.user_id == sibu_user.id || conf[:admin_filter].call(sibu_user)
17
+ redirect_to main_app.root_url, alert: "Vous n'êtes pas autorisé(e) à consulter cette page."
18
+ end
19
+ end
20
+ end
13
21
  end
14
22
  end
@@ -101,9 +101,9 @@ module Sibu
101
101
  @content_type = params[:content_type]
102
102
  @links = @site.pages_path_by_id if @site
103
103
  @element = @entity.element(*@section_id.split('|'), *@element_id.split('|'))
104
- @repeat = params[:repeat]
104
+ @repeat = params[:repeat] == 'true'
105
+ @children = params[:children] == 'true'
105
106
  @size = params[:size].blank? ? :medium : params[:size].to_sym
106
- @children = params[:children]
107
107
  end
108
108
 
109
109
  def update_element
@@ -146,7 +146,6 @@ module Sibu
146
146
  end
147
147
 
148
148
  def update_section
149
- # {"utf8"=>"✓", "section"=>{"color"=>"#AFCA0B", "filters"=>"school_camps"}, "section_id"=>"cs1536301729", "refresh"=>"true", "commit"=>"Valider", "site_id"=>"3", "id"=>"1392"}
150
149
  @entity.section(params[:section_id]).merge!(section_params)
151
150
  logger.debug @entity.section(params[:section_id])
152
151
  @updated = @entity.save
@@ -161,10 +160,12 @@ module Sibu
161
160
  def set_page
162
161
  @page = Sibu::Page.find(params[:id])
163
162
  @site = Sibu::Site.includes(:pages).find(@page.site_id) if @page
163
+ check_site_ownership!
164
164
  end
165
165
 
166
166
  def set_site
167
167
  @site = Sibu::Site.find(params[:site_id])
168
+ check_site_ownership!
168
169
  end
169
170
 
170
171
  def set_edit_context
@@ -70,6 +70,7 @@ module Sibu
70
70
 
71
71
  def set_site
72
72
  @site = Sibu::Site.find(params[:id])
73
+ check_site_ownership!
73
74
  end
74
75
 
75
76
  def site_params
@@ -36,26 +36,49 @@ module Sibu
36
36
  end
37
37
 
38
38
  [:h1, :h2, :h3, :h4, :h5, :h6, :span].each do |t|
39
- define_method(t) do |elt, html_opts = {}|
40
- defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "text" => DEFAULT_TEXT}
39
+ define_method(t) do |elt, html_opts = {}, &block|
40
+ defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "text" => Sibu::DEFAULT_TEXT}
41
41
  content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
42
42
  html_opts.merge!({data: {id: elt_id(elt), type: "text"}}) if action_name != 'show'
43
- content_tag(t, raw(content["text"]).html_safe, html_opts)
43
+ if block
44
+ @sb_section = (@sb_section || []) + [elt_id(elt)]
45
+ html_output = content_tag(t, capture(content, nested_elements(elt), &block), html_opts)
46
+ @sb_section -= [elt_id(elt)]
47
+ html_output
48
+ else
49
+ content_tag(t, raw(content["text"]).html_safe, html_opts)
50
+ end
44
51
  end
45
52
  end
46
53
 
47
- def p(elt, opts = {})
48
- repeat = opts.delete(:repeat)
49
- defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "text" => DEFAULT_PARAGRAPH}
50
- content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
51
- opts.merge!({data: {id: elt_id(elt), repeat: repeat, type: "paragraph"}}) if action_name != 'show'
52
- content_tag(:div, content_tag(:p, raw(content["text"]).html_safe), opts)
54
+ [:div, :section, :article, :aside, :header, :footer, :nav, :main, :ul].each do |t|
55
+ define_method(t) do |elt, html_opts = {}, &block|
56
+ t_id = elt.is_a?(Hash) ? elt["id"] : elt
57
+ @sb_section = (@sb_section || []) + [t_id]
58
+ html_opts = {"id" => t_id}.merge(html_opts)
59
+ html_opts.merge!(@sb_section.length == 1 ? {"data-sb-id" => t_id, "data-sb-entity" => @sb_entity == @site ? 'site' : 'page'} : {"data-id" => elt_id(elt), "data-type" => "group", "data-repeat" => false, "data-children" => false}) if action_name != 'show'
60
+ html_output = content_tag(t, capture(current_elt(elt), nested_elements(t_id), &block), html_opts)
61
+ @sb_section -= [t_id]
62
+ html_output
63
+ end
53
64
  end
54
65
 
55
66
  def sb
56
67
  self
57
68
  end
58
69
 
70
+ def join_tokens(tokens, suffix)
71
+ (tokens + [suffix]).select {|t| !t.blank?}.join("|")
72
+ end
73
+
74
+ def nested_elements(id)
75
+ element_id = elt_id(id)
76
+ element_id_tokens = (@sb_section + element_id.split("|")).uniq
77
+ nested_elts = @sb_entity.elements(*element_id_tokens)
78
+ nested_elts.blank? ? [{"id" => element_id.split("|").last, "data-id" => join_tokens(element_id_tokens[1..-1], "#{element_id}0")}] :
79
+ nested_elts.map {|e| e.merge({"data-id" => join_tokens(element_id_tokens[1..-1], e['id'])})}
80
+ end
81
+
59
82
  def select_element(id)
60
83
  @sb_entity.element(*@sb_section, id)
61
84
  end
@@ -65,11 +88,19 @@ module Sibu
65
88
  items.blank? ? [{"id" => "el#{Time.current.to_i}"}] : items
66
89
  end
67
90
 
91
+ def p(elt, opts = {})
92
+ repeat = opts.delete(:repeat)
93
+ defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "text" => Sibu::DEFAULT_PARAGRAPH}
94
+ content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
95
+ opts.merge!({data: {id: elt_id(elt), repeat: repeat, type: "paragraph"}}) if action_name != 'show'
96
+ content_tag(:div, content_tag(:p, raw(content["text"]).html_safe), opts)
97
+ end
98
+
68
99
  def img(elt, opts = {})
69
100
  wrapper = opts.delete(:wrapper)
70
101
  repeat = opts.delete(:repeat)
71
102
  size = opts.delete(:size)
72
- defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "src" => DEFAULT_IMG}
103
+ defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "src" => Sibu::DEFAULT_IMG}
73
104
  content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
74
105
  if action_name == 'show'
75
106
  content["src"] = ("/#{conf[:deployment_path]}" + content["src"]) if @online && conf[:deployment_path]
@@ -99,7 +130,7 @@ module Sibu
99
130
  end
100
131
 
101
132
  def form_label(elt, html_opts = {}, &block)
102
- defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "text" => DEFAULT_TEXT}
133
+ defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "text" => Sibu::DEFAULT_TEXT}
103
134
  content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
104
135
  html_opts.merge!({data: {id: elt_id(elt), type: "text"}}) if action_name != 'show'
105
136
  content_tag(:label, raw(content["text"]).html_safe, html_opts)
@@ -133,9 +164,20 @@ module Sibu
133
164
 
134
165
  alias site sb_site
135
166
 
167
+ def render_page_section(s)
168
+ @sb_section = [s['id']]
169
+ @sb_entity = @page
170
+ render partial: "shared/#{@site.section_template(s)}",
171
+ locals: {sibu: self, sibu_section: s, sibu_attrs: sibu_attributes(s).html_safe}
172
+ end
173
+
174
+ def sibu_attributes(section)
175
+ action_name != 'show' ? ('data-sb-id="' + section['id'] + '" data-sb-entity="page"') : ''
176
+ end
177
+
136
178
  def section(id, tag, html_opts = {}, &block)
137
179
  @sb_section = [id]
138
- opts = action_name != 'show' ? html_opts.merge({"data-sb-id" => id, "data-sb-repeat" => @sb_entity != @site, "data-sb-entity" => @sb_entity == @site ? 'site' : 'page'}) : html_opts
180
+ opts = action_name != 'show' ? html_opts.merge({"data-sb-id" => id, "data-sb-entity" => @sb_entity == @site ? 'site' : 'page'}) : html_opts
139
181
  content_tag(tag, capture(self, &block), opts)
140
182
  end
141
183
 
@@ -155,8 +197,9 @@ module Sibu
155
197
  def link(elt, html_opts = {}, &block)
156
198
  repeat = html_opts.delete(:repeat)
157
199
  children = html_opts.delete(:children)
158
- defaults = {"id" => elt_id(elt), "value" => "", "text" => DEFAULT_TEXT}
159
- content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
200
+ defaults = {"id" => elt_id(elt), "value" => "", "text" => Sibu::DEFAULT_TEXT}
201
+ link_elt = current_elt(elt)
202
+ content = defaults.merge(link_elt)
160
203
  val = content.delete("value") || ""
161
204
  text = content.delete("text")
162
205
  html_opts.merge!({data: {id: elt_id(elt), type: "link", repeat: repeat, children: children}}) if action_name != 'show'
@@ -172,16 +215,18 @@ module Sibu
172
215
  else
173
216
  content["href"] = @links.keys.include?(val.to_s) ? (action_name == 'show' ? link_path(val) : site_page_edit_content_path(@site.id, val)) : '#'
174
217
  end
175
- # Note : sends elts in given order
176
218
  if block_given?
177
- content_tag(:a, capture(*([raw(text)] + elts(elt)), &block), content.merge(html_opts).except("elements"))
219
+ @sb_section = (@sb_section || []) + [elt_id(elt)]
220
+ html_output = content_tag(:a, capture(link_elt, elts(elt), &block), content.merge(html_opts).except("elements"))
221
+ @sb_section -= [elt_id(elt)]
222
+ html_output
178
223
  else
179
224
  content_tag(:a, raw(text), content.merge(html_opts).except("elements"))
180
225
  end
181
226
  end
182
227
 
183
228
  def interactive_map(elt, html_opts = {})
184
- defaults = {"data-lat" => "45.68854", "data-lng" => "5.91587", "data-title" => DEFAULT_TEXT}
229
+ defaults = {"data-lat" => "45.68854", "data-lng" => "5.91587", "data-title" => Sibu::DEFAULT_TEXT}
185
230
  content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {"id" => elt}))
186
231
  html_opts.merge!({data: {id: elt_id(elt), type: "map"}}) if action_name != 'show'
187
232
  content_tag(:div, nil, content.merge(html_opts))
@@ -191,16 +236,20 @@ module Sibu
191
236
  elt.is_a?(Hash) ? (elt["data-id"] || elt["id"]) : elt
192
237
  end
193
238
 
239
+ def current_elt(elt)
240
+ (elt.is_a?(Hash) ? elt : (select_element(elt) || {})).except('elements')
241
+ end
242
+
194
243
  def default_content(type)
195
244
  case type
196
245
  when "text"
197
- {"text" => DEFAULT_TEXT}
246
+ {"text" => Sibu::DEFAULT_TEXT}
198
247
  when "link"
199
- {"value" => "", "text" => DEFAULT_TEXT}
248
+ {"value" => "", "text" => Sibu::DEFAULT_TEXT}
200
249
  when "paragraph"
201
- {"text" => DEFAULT_PARAGRAPH}
250
+ {"text" => Sibu::DEFAULT_PARAGRAPH}
202
251
  when "media"
203
- {"src" => DEFAULT_IMG}
252
+ {"src" => Sibu::DEFAULT_IMG}
204
253
  when "embed"
205
254
  {"code" => '<p>Contenu HTML personnalisé (iframe, etc...)</p>'}
206
255
  end
@@ -35,7 +35,6 @@ module Sibu
35
35
  if is_home == 'true'
36
36
  self.path = prefix
37
37
  else
38
- self.path = "#{prefix}#{name.parameterize}" if self.path.blank?
39
38
  self.path = "#{prefix}#{name.parameterize}" if self.path.blank? || force_update
40
39
  end
41
40
  end
@@ -51,6 +51,13 @@ module Sibu
51
51
  pages.where(id: page_id).select(:id, :path).first
52
52
  end
53
53
 
54
+ def update_paths
55
+ pages.each do |p|
56
+ p.update_path(true)
57
+ p.save
58
+ end
59
+ end
60
+
54
61
  def save_and_init
55
62
  if valid?
56
63
  self.sections = site_template.sections
@@ -6,7 +6,7 @@ module Sibu
6
6
  store :default_styles, accessors: [:primary_font, :secondary_font, :primary_color, :secondary_color], coder: JSON
7
7
 
8
8
  def reference
9
- name.parameterize.gsub('-', '_')
9
+ ref || name.parameterize.gsub('-', '_')
10
10
  end
11
11
 
12
12
  def available_sections(path_prefix = 'app/views/shared')
@@ -3,12 +3,11 @@
3
3
  <head>
4
4
  <title><%= conf[:title] %></title>
5
5
  <%= stylesheet_link_tag 'sibu/sibu', media: 'all' %>
6
- <%= stylesheet_link_tag "#{conf[:stylesheet]}-edit", media: 'all' %>
7
- <%= javascript_include_tag 'sibu/sibu' %>
6
+ <%= stylesheet_link_tag conf[:stylesheet], media: 'all' %>
8
7
  <%= javascript_include_tag "#{conf[:javascript]}-edit" %>
9
8
  <% if @site %>
10
9
  <%= stylesheet_link_tag (conf[:custom_styles] ? @site.style_url : @site.site_template.path), media: "all" %>
11
- <%= javascript_include_tag "#{@site.site_template.path}-core" %>
10
+ <%= javascript_include_tag @site.site_template.path %>
12
11
  <% end %>
13
12
  <%= csrf_meta_tags %>
14
13
  <%= yield :styles %>
@@ -42,46 +41,53 @@
42
41
  </div>
43
42
  <% end %>
44
43
  <% end %>
44
+ <%= javascript_include_tag 'sibu/sibu' %>
45
45
  <script>
46
- var rootElt = $('html, body');
47
-
48
- $(function () {
46
+ document.addEventListener("DOMContentLoaded", function() {
49
47
  initOverlays();
50
48
  sibuCallback("editContent");
51
49
  <% unless @edit_section.blank? %>
52
- $("[data-sb-overlay='<%= @edit_section %>']").click();
50
+ document.querySelector("[data-sb-overlay='<%= @edit_section %>']").click();
53
51
  <% end %>
54
52
  });
55
53
 
56
54
  function setEditMode(section, overlay, left, top, width, height) {
57
- var editMode = $("#edit_mode_overlay");
58
- editMode.find(".overlay_top").css("height", top);
59
- editMode.find(".overlay_bottom").css("top", top + height);
60
- editMode.find(".overlay_left").css({"height": height, "width": left, "top": top});
61
- editMode.find(".overlay_right").css({"height": height, "left": left + width, "top": top});
62
- editMode.find(".edit_mode_actions").css({"top": (top <= 120 ? (top + height) : (top - 40 - 20)), left: left, width: width});
63
- editMode.find("#edit_section_msg").text("Modifier la section");
64
- editMode.show();
65
- if(!section.data('sb-repeat')) {
66
- editMode.find("#new_section_before").hide();
67
- editMode.find("#new_section_after").hide();
68
- editMode.find("#delete_section").hide();
55
+ var editMode = document.querySelector("#edit_mode_overlay");
56
+ editMode.querySelector(".overlay_top").style.height = top + "px";
57
+ editMode.querySelector(".overlay_bottom").style.top = top + height + "px";
58
+ var leftOverlay = editMode.querySelector(".overlay_left"), rightOverlay = editMode.querySelector(".overlay_right"),
59
+ editModeActions = editMode.querySelector(".edit_mode_actions");
60
+ leftOverlay.style.height = height + "px";
61
+ leftOverlay.style.width = left + "px";
62
+ leftOverlay.style.top = top + "px";
63
+ rightOverlay.style.height = height + "px";
64
+ rightOverlay.style.left = left + width + "px";
65
+ rightOverlay.style.top = top + "px";
66
+ editModeActions.style.top = (top <= 120 ? (top + height) : (top - 40 - 20)) + "px";
67
+ editModeActions.style.left = left + "px";
68
+ editModeActions.style.width = width + "px";
69
+ editMode.querySelector("#edit_section_msg").innerText = "Modifier la section";
70
+ editMode.style.display = "block";
71
+ if(section.getAttribute('data-sb-entity') === 'site') {
72
+ editMode.querySelector("#new_section_before").style.display = "none";
73
+ editMode.querySelector("#new_section_after").style.display = "none";
74
+ editMode.querySelector("#delete_section").style.display = "none";
69
75
  } else {
70
- editMode.find("#new_section_before").show();
71
- editMode.find("#new_section_after").show();
72
- editMode.find("#delete_section").show();
76
+ editMode.querySelector("#new_section_before").style.display = "block";
77
+ editMode.querySelector("#new_section_after").style.display = "block";
78
+ editMode.querySelector("#delete_section").style.display = "block";
73
79
  }
74
- rootElt.animate({scrollTop: top}, 500);
75
- section.addClass('sb-editing');
80
+ window.scrollTo(0, top);
81
+ section.classList.add('sb-editing');
76
82
  initInnerOverlays(section);
77
- $("#edit_overlays").html("");
83
+ document.querySelector("#edit_overlays").innerHTML = "";
78
84
  }
79
85
 
80
86
  function cancelEditMode() {
81
87
  refreshAfterEdit(false);
82
- $("#edit_mode_overlay").hide();
88
+ document.querySelector("#edit_mode_overlay").style.display = "none";
83
89
  cancelEdit();
84
- $(".sb-editing").removeClass("sb-editing");
90
+ document.querySelector(".sb-editing").classList.remove("sb-editing");
85
91
  initOverlays();
86
92
  if(typeof editCancelledCallback === "function") {
87
93
  editCancelledCallback();
@@ -89,110 +95,109 @@
89
95
  }
90
96
 
91
97
  function newSection(isAfter) {
92
- var section = $(".sb-editing").first();
93
- var sectionsPanel = $("#sections_panel");
94
- sectionsPanel.html(
98
+ var section = document.querySelector(".sb-editing");
99
+ var sectionsPanel = document.querySelector("#sections_panel");
100
+ sectionsPanel.innerHTML =
95
101
  '<div class="sibu_panel sibu_view"><h2>Choix du type de section</h2></div>' +
96
102
  '<div><div class="sibu_sections sibu_site_content" style="text-align: center;">Chargement en cours...</div></div>' +
97
- '<div class="sibu_panel sibu_view"><div class="sibu_actions"><a href="#" onclick="cancelSectionsEdit(); return false;">Annuler</a></div></div>'
98
- );
99
- sectionsPanel.slideDown("fast");
100
- $.ajax({
101
- url: "<%= new_section_site_page_path(@site.id, @page.id) %>",
102
- method: "GET",
103
- data: {
104
- section_id: section.data("sb-id"),
105
- entity: section.data("sb-entity"),
103
+ '<div class="sibu_panel sibu_view"><div class="sibu_actions"><a href="#" onclick="cancelSectionsEdit(); return false;">Annuler</a></div></div>';
104
+ sectionsPanel.classList.add("active");
105
+ sendXmlHttpRequest(
106
+ "GET",
107
+ "<%= new_section_site_page_path(@site.id, @page.id) %>",
108
+ {
109
+ section_id: section.getAttribute("data-sb-id"),
110
+ entity: section.getAttribute("data-sb-entity"),
106
111
  after: isAfter
107
112
  }
108
- })
113
+ );
109
114
  }
110
115
 
111
116
  function editSection() {
112
- var section = $(".sb-editing").first();
113
- $.ajax({
114
- url: "<%= edit_section_site_page_path(@site.id, @page.id) %>",
115
- method: "GET",
116
- data: {
117
- section_id: section.data("sb-id"),
118
- entity: section.data("sb-entity")
117
+ var section = document.querySelector(".sb-editing");
118
+ sendXmlHttpRequest(
119
+ "GET",
120
+ "<%= edit_section_site_page_path(@site.id, @page.id) %>",
121
+ {
122
+ section_id: section.getAttribute("data-sb-id"),
123
+ entity: section.getAttribute("data-sb-entity")
119
124
  }
120
- })
125
+ );
121
126
  }
122
127
 
123
128
  function deleteSection() {
124
129
  if (window.confirm("Supprimer la section ?")) {
125
- var section = $(".sb-editing").first();
126
- $.ajax({
127
- url: "<%= delete_section_site_page_path(@site.id, @page.id) %>",
128
- method: "DELETE",
129
- data: {
130
- section_id: section.data("sb-id"),
131
- entity: section.data("sb-entity")
130
+ var section = document.querySelector(".sb-editing");
131
+ sendXmlHttpRequest(
132
+ "DELETE",
133
+ "<%= delete_section_site_page_path(@site.id, @page.id) %>",
134
+ {
135
+ section_id: section.getAttribute("data-sb-id"),
136
+ entity: section.getAttribute("data-sb-entity")
132
137
  }
133
- })
138
+ );
134
139
  }
135
140
  }
136
141
 
137
142
  function cloneElement(entity, sectionId, elementId) {
138
143
  if (window.confirm("Dupliquer l'élément ?")) {
139
- $.ajax({
140
- url: "<%= clone_element_site_page_path(@site.id, @page.id) %>",
141
- method: "POST",
142
- data: {
144
+ sendXmlHttpRequest(
145
+ "POST",
146
+ "<%= clone_element_site_page_path(@site.id, @page.id) %>",
147
+ {
143
148
  section_id: sectionId,
144
149
  element_id: elementId,
145
150
  entity: entity
146
151
  }
147
- })
152
+ );
148
153
  }
149
154
  }
150
155
 
151
156
  function deleteElement(entity, sectionId, elementId) {
152
157
  if (window.confirm("Supprimer l'élément ?")) {
153
- $.ajax({
154
- url: "<%= delete_element_site_page_path(@site.id, @page.id) %>",
155
- method: "DELETE",
156
- data: {
158
+ sendXmlHttpRequest(
159
+ "DELETE",
160
+ "<%= delete_element_site_page_path(@site.id, @page.id) %>",
161
+ {
157
162
  section_id: sectionId,
158
163
  element_id: elementId,
159
164
  entity: entity
160
165
  }
161
- })
166
+ );
162
167
  }
163
168
  }
164
169
 
165
170
  function addChildElement(entity, sectionId, elementId) {
166
171
  if (window.confirm("Ajouter un sous-menu ?")) {
167
- $.ajax({
168
- url: "<%= child_element_site_page_path(@site.id, @page.id) %>",
169
- method: "POST",
170
- data: {
172
+ sendXmlHttpRequest(
173
+ "POST",
174
+ "<%= child_element_site_page_path(@site.id, @page.id) %>",
175
+ {
171
176
  section_id: sectionId,
172
177
  element_id: elementId,
173
178
  entity: entity
174
179
  }
175
- })
180
+ );
176
181
  }
177
182
  }
178
183
 
179
184
  function cancelEdit() {
180
- $("#edit_panel").slideUp("fast");
181
- $("#edit_panel").html("");
185
+ document.querySelector("#edit_panel").classList.remove("active");
186
+ document.querySelector("#edit_panel").innerHTML = "";
182
187
  document.body.style.overflow = "initial";
183
188
  }
184
189
 
185
190
  function cancelSectionsEdit() {
186
- $("#sections_panel").slideUp("fast");
187
- $("#sections_panel").html("");
191
+ document.querySelector("#edit_panel").classList.remove("active");
192
+ document.querySelector("#sections_panel").innerHTML = "";
188
193
  document.body.style.overflow = "initial";
189
194
  }
190
195
 
191
196
  function editContent(eltId, sectionId, entity, repeat, contentType, size, children) {
192
- $.ajax({
193
- url: "<%= edit_element_site_page_path(@site.id, @page.id) %>",
194
- method: "GET",
195
- data: {
197
+ sendXmlHttpRequest(
198
+ "GET",
199
+ "<%= edit_element_site_page_path(@site.id, @page.id, format: :js) %>",
200
+ {
196
201
  element_id: eltId,
197
202
  section_id: sectionId,
198
203
  entity: entity,
@@ -201,60 +206,112 @@
201
206
  size: size,
202
207
  children: children
203
208
  }
204
- })
209
+ );
205
210
  }
206
211
 
207
212
  function initInnerOverlays(section) {
208
- var editables = section.find("[data-type]");
209
- editables.off();
210
- editables.hover(function(evt) {
211
- evt.stopPropagation();
212
- $(this).addClass("sb-editable");
213
- }, function() {
214
- $(this).removeClass("sb-editable");
215
- });
216
- editables.click(function(evt) {
217
- evt.stopPropagation();
218
- evt.preventDefault();
219
- var elt = $(this), eltId = elt.data("id"), repeat = elt.data("repeat"), type = elt.data("type"),
220
- size = elt.data("size"), children = elt.data("children");
221
- var sectionId = section.data("sb-id"), entity = section.data("sb-entity");
222
- editContent(eltId, sectionId, entity, repeat, type, size, children);
223
- })
213
+ var editables = section.querySelectorAll("[data-type]");
214
+ for (var i = 0; i < editables.length; i++) {
215
+ if (editables[i].getAttribute("data-type") !== 'group' || editables[i].getAttribute("data-repeat") !== 'false' || editables[i].getAttribute("data-children") !== 'false') {
216
+ editables[i].addEventListener("mouseenter", function(evt) {
217
+ evt.stopPropagation();
218
+ evt.currentTarget.classList.add("sb-editable");
219
+ });
220
+ editables[i].addEventListener("mouseleave", function(evt) {
221
+ evt.currentTarget.classList.remove("sb-editable");
222
+ });
223
+ editables[i].addEventListener("click", function(evt) {
224
+ evt.stopPropagation();
225
+ evt.preventDefault();
226
+ var elt = evt.currentTarget, eltId = elt.getAttribute("data-id"), repeat = elt.getAttribute("data-repeat"),
227
+ type = elt.getAttribute("data-type"), size = elt.getAttribute("data-size"), children = elt.getAttribute("data-children");
228
+ var sectionId = section.getAttribute("data-sb-id"), entity = section.getAttribute("data-sb-entity");
229
+ editContent(eltId, sectionId, entity, repeat, type, size, children);
230
+ });
231
+ }
232
+ }
224
233
  }
225
234
 
226
235
  function initOverlays() {
227
- var container = $("#edit_overlays");
228
- container.html("");
229
- $("[data-sb-id]").each(function() {
230
- var section = $(this);
231
- var offset = section.offset();
232
- var yOffset = offset.top - $(".sibu_content_panel").offset().top;
233
- var width = section.outerWidth(), height = (section.outerHeight() === 0 ? childrenHeight(section) : section.outerHeight());
234
- var overlay = $("<div data-sb-overlay='" + section.attr("data-sb-id") + "'>Modifier</div>");
235
- container.append(overlay);
236
- overlay.css({top: yOffset, left: offset.left, width: width, height: height});
237
- overlay.hover(function() {
238
- $(this).css("opacity", 1);
239
- }, function() {
240
- $(this).css("opacity", 0);
241
- });
242
- overlay.click(function() {
243
- setEditMode(section, $(this), offset.left, yOffset, width, height);
244
- })
245
- });
236
+ var container = document.querySelector("#edit_overlays"), sections = document.querySelectorAll("[data-sb-id]");
237
+ container.innerHTML = "";
238
+
239
+ for (var i = 0; i < sections.length; i++) {
240
+ var sectionBox = sections[i].getBoundingClientRect();
241
+ var yOffset = sectionBox.top - document.querySelector(".sibu_content_panel").getBoundingClientRect().top;
242
+ var width = sections[i].offsetWidth, height = (sections[i].offsetHeight === 0 ? childrenHeight(sections[i]) : sections[i].offsetHeight);
243
+ var overlay = document.createElement("div");
244
+ overlay.setAttribute("data-sb-overlay", sections[i].getAttribute("data-sb-id"));
245
+ overlay.innerHTML = "Modifier";
246
+ container.appendChild(overlay);
247
+ overlay.style.top = yOffset + "px";
248
+ overlay.style.left = sectionBox.left + "px";
249
+ overlay.style.width = width + "px";
250
+ overlay.style.height = height + "px";
251
+ overlay.addEventListener("click", (function(section, offsetLeft, offsetTop, editWidth, editHeight) {
252
+ return function(evt) {
253
+ setEditMode(section, evt.currentTarget, offsetLeft, offsetTop, editWidth, editHeight);
254
+ };
255
+ })(sections[i], sectionBox.left, yOffset, width, height));
256
+ }
246
257
  }
247
258
 
248
259
  function childrenHeight(parentElt) {
249
- var height = 0;
250
- parentElt.find("*").each(function() {
251
- var childHeight = $(this).height();
260
+ var height = 0, children = parentElt.querySelectorAll("*");
261
+ for (var i = 0; i < children.length; i++) {
262
+ var childHeight = children[i].clientHeight;
252
263
  if(childHeight > height) {
253
264
  height = childHeight;
254
265
  }
255
- });
266
+ }
256
267
  return height;
257
268
  }
269
+
270
+ function submitForm(formElt, callback) {
271
+ sendXmlHttpRequest(formElt.getAttribute("method").toUpperCase(), formElt.getAttribute("action"),
272
+ new FormData(formElt))
273
+ }
274
+
275
+ function sendXmlHttpRequest(method, url, data, callback) {
276
+ var req = new XMLHttpRequest(), param;
277
+ if (callback) {
278
+ req.onload = callback;
279
+ } else {
280
+ req.onload = function() {
281
+ eval(req.responseText);
282
+ }
283
+ }
284
+
285
+ if (method === 'GET') {
286
+ var params = [];
287
+ for(param in data ) {
288
+ if (data.hasOwnProperty(param)) {
289
+ params.push(encodeURIComponent(param) + '=' + encodeURIComponent(data[param] || ""));
290
+ }
291
+ }
292
+ req.open(method, url + '?' + params.join('&').replace(/%20/g, '+'));
293
+ req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
294
+ req.send();
295
+ } else {
296
+ if (data instanceof FormData) {
297
+ formData = data;
298
+ } else {
299
+ var formData = new FormData();
300
+ for (var key in data) {
301
+ if (data.hasOwnProperty(key)) {
302
+ formData.append(key, data[key]);
303
+ }
304
+ }
305
+ }
306
+
307
+ req.open(method, url);
308
+ req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
309
+ var token = document.getElementsByName("csrf-token")[0].content;
310
+ req.setRequestHeader('X-CSRF-Token', token);
311
+
312
+ req.send(formData);
313
+ }
314
+ }
258
315
  </script>
259
316
  <%= yield :site_scripts %>
260
317
  <%= yield :page_scripts %>