sibu 0.9.4 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +81 -4
  3. data/app/assets/javascripts/sibu/sibu.js.erb +17 -3
  4. data/app/assets/javascripts/tabs/van11y-accessible-tab-panel-aria.js +122 -124
  5. data/app/assets/stylesheets/sibu/defaults.scss +72 -80
  6. data/app/assets/stylesheets/sibu/sibu.css +8 -0
  7. data/app/controllers/sibu/application_controller.rb +8 -0
  8. data/app/controllers/sibu/pages_controller.rb +11 -4
  9. data/app/controllers/sibu/sites_controller.rb +6 -1
  10. data/app/helpers/sibu/application_helper.rb +1 -1
  11. data/app/helpers/sibu/pages_helper.rb +104 -23
  12. data/app/models/sibu/page.rb +0 -1
  13. data/app/models/sibu/site.rb +7 -0
  14. data/app/models/sibu/site_template.rb +1 -1
  15. data/app/views/layouts/sibu/edit_content.html.erb +184 -125
  16. data/app/views/sibu/images/edit.js.erb +5 -3
  17. data/app/views/sibu/pages/_code_edit_panel.html.erb +3 -2
  18. data/app/views/sibu/pages/_form.html.erb +8 -0
  19. data/app/views/sibu/pages/_link_edit_panel.html.erb +6 -6
  20. data/app/views/sibu/pages/_map_edit_panel.html.erb +3 -2
  21. data/app/views/sibu/pages/_media_edit_panel.html.erb +6 -6
  22. data/app/views/sibu/pages/_new_section_panel.html.erb +1 -1
  23. data/app/views/sibu/pages/_paragraph_edit_panel.html.erb +2 -2
  24. data/app/views/sibu/pages/_text_edit_panel.html.erb +2 -2
  25. data/app/views/sibu/pages/child_element.js.erb +2 -2
  26. data/app/views/sibu/pages/clone_element.js.erb +2 -2
  27. data/app/views/sibu/pages/create_section.js.erb +1 -1
  28. data/app/views/sibu/pages/delete_element.js.erb +1 -1
  29. data/app/views/sibu/pages/delete_section.js.erb +1 -1
  30. data/app/views/sibu/pages/edit_element.js.erb +68 -66
  31. data/app/views/sibu/pages/edit_section.js.erb +6 -5
  32. data/app/views/sibu/pages/index.html.erb +2 -2
  33. data/app/views/sibu/pages/new_section.js.erb +22 -13
  34. data/app/views/sibu/pages/update_element.js.erb +2 -2
  35. data/app/views/sibu/pages/update_section.js.erb +3 -3
  36. data/config/initializers/constants.rb +5 -3
  37. data/db/migrate/20200401130601_add_ref_to_site_templates.rb +5 -0
  38. data/lib/sibu/engine.rb +0 -2
  39. data/lib/sibu/version.rb +1 -1
  40. metadata +3 -18
  41. data/app/views/sibu/pages/destroy.html.erb +0 -2
  42. data/app/views/sibu/pages/update.html.erb +0 -2
@@ -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')
@@ -2,14 +2,13 @@
2
2
  <html>
3
3
  <head>
4
4
  <title><%= conf[:title] %></title>
5
- <%= stylesheet_link_tag 'sibu/sibu', media: 'all' %>
6
- <%= stylesheet_link_tag "#{conf[:stylesheet]}-edit", media: 'all' %>
7
- <%= javascript_include_tag 'sibu/sibu' %>
8
- <%= javascript_include_tag "#{conf[:javascript]}-edit" %>
9
5
  <% if @site %>
10
6
  <%= stylesheet_link_tag (conf[:custom_styles] ? @site.style_url : @site.site_template.path), media: "all" %>
11
- <%= javascript_include_tag "#{@site.site_template.path}-core" %>
7
+ <%= javascript_include_tag @site.site_template.path %>
12
8
  <% end %>
9
+ <%= stylesheet_link_tag 'sibu/sibu', media: 'all' %>
10
+ <%= stylesheet_link_tag "#{conf[:stylesheet]}-edit", media: 'all' %>
11
+ <%= javascript_include_tag "#{conf[:javascript]}-edit" %>
13
12
  <%= csrf_meta_tags %>
14
13
  <%= yield :styles %>
15
14
  </head>
@@ -42,46 +41,50 @@
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 () {
49
- initOverlays();
46
+ document.addEventListener("DOMContentLoaded", function() {
47
+ initOverlays("<%= @edit_section || '' %>");
50
48
  sibuCallback("editContent");
51
- <% unless @edit_section.blank? %>
52
- $("[data-sb-overlay='<%= @edit_section %>']").click();
53
- <% end %>
54
49
  });
55
50
 
56
51
  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();
52
+ var editMode = document.querySelector("#edit_mode_overlay");
53
+ editMode.querySelector(".overlay_top").style.height = top + "px";
54
+ editMode.querySelector(".overlay_bottom").style.top = top + height + "px";
55
+ var leftOverlay = editMode.querySelector(".overlay_left"), rightOverlay = editMode.querySelector(".overlay_right"),
56
+ editModeActions = editMode.querySelector(".edit_mode_actions");
57
+ leftOverlay.style.height = height + "px";
58
+ leftOverlay.style.width = left + "px";
59
+ leftOverlay.style.top = top + "px";
60
+ rightOverlay.style.height = height + "px";
61
+ rightOverlay.style.left = left + width + "px";
62
+ rightOverlay.style.top = top + "px";
63
+ editModeActions.style.top = (top <= 120 ? (top + height) : (top - 40 - 20)) + "px";
64
+ editModeActions.style.left = left + "px";
65
+ editModeActions.style.width = width + "px";
66
+ editMode.querySelector("#edit_section_msg").innerText = "Modifier la section";
67
+ editMode.style.display = "block";
68
+ if(section.getAttribute('data-sb-entity') === 'site') {
69
+ editMode.querySelector("#new_section_before").style.display = "none";
70
+ editMode.querySelector("#new_section_after").style.display = "none";
71
+ editMode.querySelector("#delete_section").style.display = "none";
69
72
  } else {
70
- editMode.find("#new_section_before").show();
71
- editMode.find("#new_section_after").show();
72
- editMode.find("#delete_section").show();
73
+ editMode.querySelector("#new_section_before").style.display = "block";
74
+ editMode.querySelector("#new_section_after").style.display = "block";
75
+ editMode.querySelector("#delete_section").style.display = "block";
73
76
  }
74
- rootElt.animate({scrollTop: top}, 500);
75
- section.addClass('sb-editing');
77
+ window.scrollTo(0, top);
78
+ section.classList.add('sb-editing');
76
79
  initInnerOverlays(section);
77
- $("#edit_overlays").html("");
80
+ document.querySelector("#edit_overlays").innerHTML = "";
78
81
  }
79
82
 
80
83
  function cancelEditMode() {
81
84
  refreshAfterEdit(false);
82
- $("#edit_mode_overlay").hide();
85
+ document.querySelector("#edit_mode_overlay").style.display = "none";
83
86
  cancelEdit();
84
- $(".sb-editing").removeClass("sb-editing");
87
+ document.querySelector(".sb-editing").classList.remove("sb-editing");
85
88
  initOverlays();
86
89
  if(typeof editCancelledCallback === "function") {
87
90
  editCancelledCallback();
@@ -89,110 +92,109 @@
89
92
  }
90
93
 
91
94
  function newSection(isAfter) {
92
- var section = $(".sb-editing").first();
93
- var sectionsPanel = $("#sections_panel");
94
- sectionsPanel.html(
95
+ var section = document.querySelector(".sb-editing");
96
+ var sectionsPanel = document.querySelector("#sections_panel");
97
+ sectionsPanel.innerHTML =
95
98
  '<div class="sibu_panel sibu_view"><h2>Choix du type de section</h2></div>' +
96
99
  '<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"),
100
+ '<div class="sibu_panel sibu_view"><div class="sibu_actions"><a href="#" onclick="cancelSectionsEdit(); return false;">Annuler</a></div></div>';
101
+ sectionsPanel.classList.add("active");
102
+ sendXmlHttpRequest(
103
+ "GET",
104
+ "<%= new_section_site_page_path(@site.id, @page.id) %>",
105
+ {
106
+ section_id: section.getAttribute("data-sb-id"),
107
+ entity: section.getAttribute("data-sb-entity"),
106
108
  after: isAfter
107
109
  }
108
- })
110
+ );
109
111
  }
110
112
 
111
113
  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")
114
+ var section = document.querySelector(".sb-editing");
115
+ sendXmlHttpRequest(
116
+ "GET",
117
+ "<%= edit_section_site_page_path(@site.id, @page.id) %>",
118
+ {
119
+ section_id: section.getAttribute("data-sb-id"),
120
+ entity: section.getAttribute("data-sb-entity")
119
121
  }
120
- })
122
+ );
121
123
  }
122
124
 
123
125
  function deleteSection() {
124
126
  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")
127
+ var section = document.querySelector(".sb-editing");
128
+ sendXmlHttpRequest(
129
+ "DELETE",
130
+ "<%= delete_section_site_page_path(@site.id, @page.id) %>",
131
+ {
132
+ section_id: section.getAttribute("data-sb-id"),
133
+ entity: section.getAttribute("data-sb-entity")
132
134
  }
133
- })
135
+ );
134
136
  }
135
137
  }
136
138
 
137
139
  function cloneElement(entity, sectionId, elementId) {
138
140
  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: {
141
+ sendXmlHttpRequest(
142
+ "POST",
143
+ "<%= clone_element_site_page_path(@site.id, @page.id) %>",
144
+ {
143
145
  section_id: sectionId,
144
146
  element_id: elementId,
145
147
  entity: entity
146
148
  }
147
- })
149
+ );
148
150
  }
149
151
  }
150
152
 
151
153
  function deleteElement(entity, sectionId, elementId) {
152
154
  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: {
155
+ sendXmlHttpRequest(
156
+ "DELETE",
157
+ "<%= delete_element_site_page_path(@site.id, @page.id) %>",
158
+ {
157
159
  section_id: sectionId,
158
160
  element_id: elementId,
159
161
  entity: entity
160
162
  }
161
- })
163
+ );
162
164
  }
163
165
  }
164
166
 
165
167
  function addChildElement(entity, sectionId, elementId) {
166
168
  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: {
169
+ sendXmlHttpRequest(
170
+ "POST",
171
+ "<%= child_element_site_page_path(@site.id, @page.id) %>",
172
+ {
171
173
  section_id: sectionId,
172
174
  element_id: elementId,
173
175
  entity: entity
174
176
  }
175
- })
177
+ );
176
178
  }
177
179
  }
178
180
 
179
181
  function cancelEdit() {
180
- $("#edit_panel").slideUp("fast");
181
- $("#edit_panel").html("");
182
+ document.querySelector("#edit_panel").classList.remove("active");
183
+ document.querySelector("#edit_panel").innerHTML = "";
182
184
  document.body.style.overflow = "initial";
183
185
  }
184
186
 
185
187
  function cancelSectionsEdit() {
186
- $("#sections_panel").slideUp("fast");
187
- $("#sections_panel").html("");
188
+ document.querySelector("#edit_panel").classList.remove("active");
189
+ document.querySelector("#sections_panel").innerHTML = "";
188
190
  document.body.style.overflow = "initial";
189
191
  }
190
192
 
191
193
  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: {
194
+ sendXmlHttpRequest(
195
+ "GET",
196
+ "<%= edit_element_site_page_path(@site.id, @page.id, format: :js) %>",
197
+ {
196
198
  element_id: eltId,
197
199
  section_id: sectionId,
198
200
  entity: entity,
@@ -201,60 +203,117 @@
201
203
  size: size,
202
204
  children: children
203
205
  }
204
- })
206
+ );
205
207
  }
206
208
 
207
209
  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
- })
210
+ var editables = section.querySelectorAll("[data-type]");
211
+ for (var i = 0; i < editables.length; i++) {
212
+ if (editables[i].getAttribute("data-type") !== 'group' || editables[i].getAttribute("data-repeat") === 'true' || editables[i].getAttribute("data-children") === 'true') {
213
+ editables[i].addEventListener("mouseenter", function(evt) {
214
+ evt.stopPropagation();
215
+ evt.currentTarget.classList.add("sb-editable");
216
+ });
217
+ editables[i].addEventListener("mouseleave", function(evt) {
218
+ evt.currentTarget.classList.remove("sb-editable");
219
+ });
220
+ editables[i].addEventListener("click", function(evt) {
221
+ evt.stopPropagation();
222
+ evt.preventDefault();
223
+ var elt = evt.currentTarget, eltId = elt.getAttribute("data-id"), repeat = elt.getAttribute("data-repeat"),
224
+ type = elt.getAttribute("data-type"), size = elt.getAttribute("data-size"), children = elt.getAttribute("data-children");
225
+ var sectionId = section.getAttribute("data-sb-id"), entity = section.getAttribute("data-sb-entity");
226
+ editContent(eltId, sectionId, entity, repeat, type, size, children);
227
+ });
228
+ }
229
+ }
224
230
  }
225
231
 
226
- 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
- });
232
+ function initOverlays(activeSection = "") {
233
+ setTimeout(function() {
234
+ var container = document.querySelector("#edit_overlays"), sections = document.querySelectorAll("[data-sb-id]");
235
+ container.innerHTML = "";
236
+
237
+ for (var i = 0; i < sections.length; i++) {
238
+ var sectionBox = sections[i].getBoundingClientRect();
239
+ var yOffset = sectionBox.top - document.querySelector(".sibu_content_panel").getBoundingClientRect().top;
240
+ var width = sections[i].offsetWidth, height = (sections[i].offsetHeight === 0 ? childrenHeight(sections[i]) : sections[i].offsetHeight);
241
+ var overlay = document.createElement("div");
242
+ overlay.setAttribute("data-sb-overlay", sections[i].getAttribute("data-sb-id"));
243
+ overlay.innerHTML = "Modifier";
244
+ container.appendChild(overlay);
245
+ overlay.style.top = yOffset + "px";
246
+ overlay.style.left = sectionBox.left + "px";
247
+ overlay.style.width = width + "px";
248
+ overlay.style.height = height + "px";
249
+ overlay.addEventListener("click", (function(section, offsetLeft, offsetTop, editWidth, editHeight) {
250
+ return function(evt) {
251
+ setEditMode(section, evt.currentTarget, offsetLeft, offsetTop, editWidth, editHeight);
252
+ };
253
+ })(sections[i], sectionBox.left, yOffset, width, height));
254
+ }
255
+ if (activeSection) {
256
+ document.querySelector("[data-sb-overlay='" + activeSection + "']").click();
257
+ }
258
+ }, 800);
246
259
  }
247
260
 
248
261
  function childrenHeight(parentElt) {
249
- var height = 0;
250
- parentElt.find("*").each(function() {
251
- var childHeight = $(this).height();
262
+ var height = 0, children = parentElt.querySelectorAll("*");
263
+ for (var i = 0; i < children.length; i++) {
264
+ var childHeight = children[i].clientHeight;
252
265
  if(childHeight > height) {
253
266
  height = childHeight;
254
267
  }
255
- });
268
+ }
256
269
  return height;
257
270
  }
271
+
272
+ function submitForm(formElt, callback) {
273
+ sendXmlHttpRequest(formElt.getAttribute("method").toUpperCase(), formElt.getAttribute("action"),
274
+ new FormData(formElt))
275
+ }
276
+
277
+ function sendXmlHttpRequest(method, url, data, callback) {
278
+ var req = new XMLHttpRequest(), param;
279
+ if (callback) {
280
+ req.onload = callback;
281
+ } else {
282
+ req.onload = function() {
283
+ eval(req.responseText);
284
+ }
285
+ }
286
+
287
+ if (method === 'GET') {
288
+ var params = [];
289
+ for(param in data ) {
290
+ if (data.hasOwnProperty(param)) {
291
+ params.push(encodeURIComponent(param) + '=' + encodeURIComponent(data[param] || ""));
292
+ }
293
+ }
294
+ req.open(method, url + '?' + params.join('&').replace(/%20/g, '+'));
295
+ req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
296
+ req.send();
297
+ } else {
298
+ if (data instanceof FormData) {
299
+ formData = data;
300
+ } else {
301
+ var formData = new FormData();
302
+ for (var key in data) {
303
+ if (data.hasOwnProperty(key)) {
304
+ formData.append(key, data[key]);
305
+ }
306
+ }
307
+ }
308
+
309
+ req.open(method, url);
310
+ req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
311
+ var token = document.getElementsByName("csrf-token")[0].content;
312
+ req.setRequestHeader('X-CSRF-Token', token);
313
+
314
+ req.send(formData);
315
+ }
316
+ }
258
317
  </script>
259
318
  <%= yield :site_scripts %>
260
319
  <%= yield :page_scripts %>
@@ -1,3 +1,5 @@
1
- $(".sibu_edit_image").html("<%= j(render 'edit_form') %>");
2
- $(".sibu_image").removeClass("selected");
3
- $("<%= "#sibu_image_#{@image.id}" %>").addClass("selected");
1
+ document.querySelector(".sibu_edit_image").innerHTML = "<%= j(render 'edit_form') %>";
2
+ if (document.querySelector(".sibu_image.selected")) {
3
+ document.querySelector(".sibu_image.selected").classList.remove("selected");
4
+ }
5
+ document.querySelector("<%= "#sibu_image_#{@image.id}" %>").classList.add("selected");