sibu 0.9.5 → 1.0.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 (43) 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 +20 -1
  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 +97 -16
  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 +220 -126
  16. data/app/views/sibu/images/edit.js.erb +5 -3
  17. data/app/views/sibu/pages/_code_edit_panel.html.erb +4 -3
  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 +2 -2
  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.html.erb +1 -1
  31. data/app/views/sibu/pages/edit_element.js.erb +68 -66
  32. data/app/views/sibu/pages/edit_section.js.erb +6 -5
  33. data/app/views/sibu/pages/index.html.erb +3 -3
  34. data/app/views/sibu/pages/new_section.js.erb +22 -13
  35. data/app/views/sibu/pages/update_element.js.erb +2 -2
  36. data/app/views/sibu/pages/update_section.js.erb +3 -3
  37. data/app/views/sibu/sites/index.html.erb +1 -1
  38. data/db/migrate/20200401130601_add_ref_to_site_templates.rb +5 -0
  39. data/lib/sibu/engine.rb +0 -2
  40. data/lib/sibu/version.rb +1 -1
  41. metadata +3 -18
  42. data/app/views/sibu/pages/destroy.html.erb +0 -2
  43. 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,18 +2,17 @@
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>
16
- <body>
15
+ <body class="sibu_edit_content">
17
16
  <% [:top_panel, :side_panel, :content_panel, :bottom_panel].each do |panel| %>
18
17
  <% unless conf[panel].blank? %>
19
18
  <div class="<%= panel == :content_panel ? 'sibu_content_panel' : 'sibu_panel' %>">
@@ -42,46 +41,51 @@
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
+ var topPadding = top <= 120 ? 60 : 120;
78
+ window.scrollTo(0, top - topPadding);
79
+ section.classList.add('sb-editing');
76
80
  initInnerOverlays(section);
77
- $("#edit_overlays").html("");
81
+ document.querySelector("#edit_overlays").innerHTML = "";
78
82
  }
79
83
 
80
84
  function cancelEditMode() {
81
85
  refreshAfterEdit(false);
82
- $("#edit_mode_overlay").hide();
86
+ document.querySelector("#edit_mode_overlay").style.display = "none";
83
87
  cancelEdit();
84
- $(".sb-editing").removeClass("sb-editing");
88
+ document.querySelector(".sb-editing").classList.remove("sb-editing");
85
89
  initOverlays();
86
90
  if(typeof editCancelledCallback === "function") {
87
91
  editCancelledCallback();
@@ -89,95 +93,109 @@
89
93
  }
90
94
 
91
95
  function newSection(isAfter) {
92
- var section = $(".sb-editing").first();
93
- var sectionsPanel = $("#sections_panel");
94
- sectionsPanel.html(
96
+ var section = document.querySelector(".sb-editing");
97
+ var sectionsPanel = document.querySelector("#sections_panel");
98
+ sectionsPanel.innerHTML =
95
99
  '<div class="sibu_panel sibu_view"><h2>Choix du type de section</h2></div>' +
96
100
  '<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"),
101
+ '<div class="sibu_panel sibu_view"><div class="sibu_actions"><a href="#" onclick="cancelSectionsEdit(); return false;">Annuler</a></div></div>';
102
+ sectionsPanel.classList.add("active");
103
+ sendXmlHttpRequest(
104
+ "GET",
105
+ "<%= new_section_site_page_path(@site.id, @page.id) %>",
106
+ {
107
+ section_id: section.getAttribute("data-sb-id"),
108
+ entity: section.getAttribute("data-sb-entity"),
106
109
  after: isAfter
107
110
  }
108
- })
111
+ );
109
112
  }
110
113
 
111
114
  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")
115
+ var section = document.querySelector(".sb-editing");
116
+ sendXmlHttpRequest(
117
+ "GET",
118
+ "<%= edit_section_site_page_path(@site.id, @page.id) %>",
119
+ {
120
+ section_id: section.getAttribute("data-sb-id"),
121
+ entity: section.getAttribute("data-sb-entity")
119
122
  }
120
- })
123
+ );
121
124
  }
122
125
 
123
126
  function deleteSection() {
124
127
  if (window.confirm("Supprimer la section ?")) {
125
- var section = $(".sb-editing").first();
126
- Rails.ajax({
127
- url: "<%= delete_section_site_page_path(@site.id, @page.id) %>",
128
- type: "DELETE",
129
- data: new URLSearchParams({section_id: section.data("sb-id"), entity: section.data("sb-entity")}).toString()
130
- })
128
+ var section = document.querySelector(".sb-editing");
129
+ sendXmlHttpRequest(
130
+ "DELETE",
131
+ "<%= delete_section_site_page_path(@site.id, @page.id) %>",
132
+ {
133
+ section_id: section.getAttribute("data-sb-id"),
134
+ entity: section.getAttribute("data-sb-entity")
135
+ }
136
+ );
131
137
  }
132
138
  }
133
139
 
134
140
  function cloneElement(entity, sectionId, elementId) {
135
141
  if (window.confirm("Dupliquer l'élément ?")) {
136
- Rails.ajax({
137
- url: "<%= clone_element_site_page_path(@site.id, @page.id) %>",
138
- type: "POST",
139
- data: new URLSearchParams({section_id: sectionId, element_id: elementId, entity: entity})
140
- })
142
+ sendXmlHttpRequest(
143
+ "POST",
144
+ "<%= clone_element_site_page_path(@site.id, @page.id) %>",
145
+ {
146
+ section_id: sectionId,
147
+ element_id: elementId,
148
+ entity: entity
149
+ }
150
+ );
141
151
  }
142
152
  }
143
153
 
144
154
  function deleteElement(entity, sectionId, elementId) {
145
155
  if (window.confirm("Supprimer l'élément ?")) {
146
- Rails.ajax({
147
- url: "<%= delete_element_site_page_path(@site.id, @page.id) %>",
148
- type: "DELETE",
149
- data: new URLSearchParams({section_id: sectionId, element_id: elementId, entity: entity})
150
- })
156
+ sendXmlHttpRequest(
157
+ "DELETE",
158
+ "<%= delete_element_site_page_path(@site.id, @page.id) %>",
159
+ {
160
+ section_id: sectionId,
161
+ element_id: elementId,
162
+ entity: entity
163
+ }
164
+ );
151
165
  }
152
166
  }
153
167
 
154
168
  function addChildElement(entity, sectionId, elementId) {
155
169
  if (window.confirm("Ajouter un sous-menu ?")) {
156
- Rails.ajax({
157
- url: "<%= child_element_site_page_path(@site.id, @page.id) %>",
158
- type: "POST",
159
- data: new URLSearchParams({section_id: sectionId, element_id: elementId, entity: entity})
160
- })
170
+ sendXmlHttpRequest(
171
+ "POST",
172
+ "<%= child_element_site_page_path(@site.id, @page.id) %>",
173
+ {
174
+ section_id: sectionId,
175
+ element_id: elementId,
176
+ entity: entity
177
+ }
178
+ );
161
179
  }
162
180
  }
163
181
 
164
182
  function cancelEdit() {
165
- $("#edit_panel").slideUp("fast");
166
- $("#edit_panel").html("");
183
+ document.querySelector("#edit_panel").classList.remove("active");
184
+ document.querySelector("#edit_panel").innerHTML = "";
167
185
  document.body.style.overflow = "initial";
168
186
  }
169
187
 
170
188
  function cancelSectionsEdit() {
171
- $("#sections_panel").slideUp("fast");
172
- $("#sections_panel").html("");
189
+ document.querySelector("#edit_panel").classList.remove("active");
190
+ document.querySelector("#sections_panel").innerHTML = "";
173
191
  document.body.style.overflow = "initial";
174
192
  }
175
193
 
176
194
  function editContent(eltId, sectionId, entity, repeat, contentType, size, children) {
177
- $.ajax({
178
- url: "<%= edit_element_site_page_path(@site.id, @page.id) %>",
179
- method: "GET",
180
- data: {
195
+ sendXmlHttpRequest(
196
+ "GET",
197
+ "<%= edit_element_site_page_path(@site.id, @page.id, format: :js) %>",
198
+ {
181
199
  element_id: eltId,
182
200
  section_id: sectionId,
183
201
  entity: entity,
@@ -186,60 +204,136 @@
186
204
  size: size,
187
205
  children: children
188
206
  }
189
- })
207
+ );
190
208
  }
191
209
 
192
210
  function initInnerOverlays(section) {
193
- var editables = section.find("[data-type]");
194
- editables.off();
195
- editables.hover(function(evt) {
196
- evt.stopPropagation();
197
- $(this).addClass("sb-editable");
198
- }, function() {
199
- $(this).removeClass("sb-editable");
200
- });
201
- editables.click(function(evt) {
202
- evt.stopPropagation();
203
- evt.preventDefault();
204
- var elt = $(this), eltId = elt.data("id"), repeat = elt.data("repeat"), type = elt.data("type"),
205
- size = elt.data("size"), children = elt.data("children");
206
- var sectionId = section.data("sb-id"), entity = section.data("sb-entity");
207
- editContent(eltId, sectionId, entity, repeat, type, size, children);
208
- })
209
- }
210
-
211
- function initOverlays() {
212
- var container = $("#edit_overlays");
213
- container.html("");
214
- $("[data-sb-id]").each(function() {
215
- var section = $(this);
216
- var offset = section.offset();
217
- var yOffset = offset.top - $(".sibu_content_panel").offset().top;
218
- var width = section.outerWidth(), height = (section.outerHeight() === 0 ? childrenHeight(section) : section.outerHeight());
219
- var overlay = $("<div data-sb-overlay='" + section.attr("data-sb-id") + "'>Modifier</div>");
220
- container.append(overlay);
221
- overlay.css({top: yOffset, left: offset.left, width: width, height: height});
222
- overlay.hover(function() {
223
- $(this).css("opacity", 1);
224
- }, function() {
225
- $(this).css("opacity", 0);
226
- });
227
- overlay.click(function() {
228
- setEditMode(section, $(this), offset.left, yOffset, width, height);
229
- })
230
- });
211
+ var editables = section.querySelectorAll("[data-type]");
212
+ for (var i = 0; i < editables.length; i++) {
213
+ if (editables[i].getAttribute("data-type") !== 'group' || editables[i].getAttribute("data-repeat") === 'true' || editables[i].getAttribute("data-children") === 'true') {
214
+ editables[i].addEventListener("mouseenter", function(evt) {
215
+ evt.stopPropagation();
216
+ evt.currentTarget.classList.add("sb-editable");
217
+ });
218
+ editables[i].addEventListener("mouseleave", function(evt) {
219
+ evt.currentTarget.classList.remove("sb-editable");
220
+ });
221
+ editables[i].addEventListener("click", function(evt) {
222
+ evt.stopPropagation();
223
+ evt.preventDefault();
224
+ var elt = evt.currentTarget, eltId = elt.getAttribute("data-id"), repeat = elt.getAttribute("data-repeat"),
225
+ type = elt.getAttribute("data-type"), size = elt.getAttribute("data-size"), children = elt.getAttribute("data-children");
226
+ var sectionId = section.getAttribute("data-sb-id"), entity = section.getAttribute("data-sb-entity");
227
+ editContent(eltId, sectionId, entity, repeat, type, size, children);
228
+ });
229
+ }
230
+ }
231
+ }
232
+
233
+ function initOverlays(activeSection = "") {
234
+ setTimeout(function() {
235
+ var container = document.querySelector("#edit_overlays"), sections = document.querySelectorAll("[data-sb-id]");
236
+ container.innerHTML = "";
237
+
238
+ for (var i = 0; i < sections.length; i++) {
239
+ var sectionBox = eltBox(sections[i]);
240
+ var yOffset = sectionBox.top;
241
+ var width = sections[i].offsetWidth, height = (sections[i].offsetHeight === 0 ? childrenHeight(sections[i]) : sections[i].offsetHeight);
242
+ var overlay = document.createElement("div");
243
+ overlay.setAttribute("data-sb-overlay", sections[i].getAttribute("data-sb-id"));
244
+ overlay.innerHTML = "Modifier";
245
+ container.appendChild(overlay);
246
+ overlay.style.top = yOffset + "px";
247
+ overlay.style.left = sectionBox.left + "px";
248
+ overlay.style.width = width + "px";
249
+ overlay.style.height = height + "px";
250
+ overlay.addEventListener("click", (function(section, offsetLeft, offsetTop, editWidth, editHeight) {
251
+ return function(evt) {
252
+ setEditMode(section, evt.currentTarget, offsetLeft, offsetTop, editWidth, editHeight);
253
+ };
254
+ })(sections[i], sectionBox.left, yOffset, width, height));
255
+ }
256
+ if (activeSection) {
257
+ document.querySelector("[data-sb-overlay='" + activeSection + "']").click();
258
+ }
259
+ }, 800);
260
+ }
261
+
262
+ function eltBox(elt) {
263
+ var x, y, w, h, bbox = elt.getBoundingClientRect();
264
+ if (isIE()) {
265
+ x = bbox.left + window.scrollX;
266
+ y = bbox.top + window.scrollY;
267
+ } else {
268
+ x = bbox.x + window.scrollX;
269
+ y = bbox.y + window.scrollY;
270
+ }
271
+ w = bbox.width;
272
+ h = bbox.height;
273
+ return {top: y, left: x, width: w, height: h}
274
+ }
275
+
276
+ function isIE() {
277
+ let ua = navigator.userAgent;
278
+ return ua.indexOf("MSIE ") > -1 || ua.indexOf("Trident/") > -1;
231
279
  }
232
280
 
233
281
  function childrenHeight(parentElt) {
234
- var height = 0;
235
- parentElt.find("*").each(function() {
236
- var childHeight = $(this).height();
282
+ var height = 0, children = parentElt.querySelectorAll("*");
283
+ for (var i = 0; i < children.length; i++) {
284
+ var childHeight = children[i].clientHeight;
237
285
  if(childHeight > height) {
238
286
  height = childHeight;
239
287
  }
240
- });
288
+ }
241
289
  return height;
242
290
  }
291
+
292
+ function submitForm(formElt, callback) {
293
+ sendXmlHttpRequest(formElt.getAttribute("method").toUpperCase(), formElt.getAttribute("action"),
294
+ new FormData(formElt))
295
+ }
296
+
297
+ function sendXmlHttpRequest(method, url, data, callback) {
298
+ var req = new XMLHttpRequest(), param;
299
+ if (callback) {
300
+ req.onload = callback;
301
+ } else {
302
+ req.onload = function() {
303
+ eval(req.responseText);
304
+ }
305
+ }
306
+
307
+ if (method === 'GET') {
308
+ var params = [];
309
+ for(param in data ) {
310
+ if (data.hasOwnProperty(param)) {
311
+ params.push(encodeURIComponent(param) + '=' + encodeURIComponent(data[param] || ""));
312
+ }
313
+ }
314
+ req.open(method, url + '?' + params.join('&').replace(/%20/g, '+'));
315
+ req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
316
+ req.send();
317
+ } else {
318
+ if (data instanceof FormData) {
319
+ formData = data;
320
+ } else {
321
+ var formData = new FormData();
322
+ for (var key in data) {
323
+ if (data.hasOwnProperty(key)) {
324
+ formData.append(key, data[key]);
325
+ }
326
+ }
327
+ }
328
+
329
+ req.open(method, url);
330
+ req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
331
+ var token = document.getElementsByName("csrf-token")[0].content;
332
+ req.setRequestHeader('X-CSRF-Token', token);
333
+
334
+ req.send(formData);
335
+ }
336
+ }
243
337
  </script>
244
338
  <%= yield :site_scripts %>
245
339
  <%= yield :page_scripts %>