sibu 0.9.5 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
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 %>