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.
- checksums.yaml +4 -4
- data/README.md +81 -4
- data/app/assets/javascripts/sibu/sibu.js.erb +17 -3
- data/app/assets/javascripts/tabs/van11y-accessible-tab-panel-aria.js +122 -124
- data/app/assets/stylesheets/sibu/defaults.scss +72 -80
- data/app/assets/stylesheets/sibu/sibu.css +20 -1
- data/app/controllers/sibu/application_controller.rb +8 -0
- data/app/controllers/sibu/pages_controller.rb +11 -4
- data/app/controllers/sibu/sites_controller.rb +6 -1
- data/app/helpers/sibu/application_helper.rb +1 -1
- data/app/helpers/sibu/pages_helper.rb +97 -16
- data/app/models/sibu/page.rb +0 -1
- data/app/models/sibu/site.rb +7 -0
- data/app/models/sibu/site_template.rb +1 -1
- data/app/views/layouts/sibu/edit_content.html.erb +220 -126
- data/app/views/sibu/images/edit.js.erb +5 -3
- data/app/views/sibu/pages/_code_edit_panel.html.erb +4 -3
- data/app/views/sibu/pages/_form.html.erb +8 -0
- data/app/views/sibu/pages/_link_edit_panel.html.erb +6 -6
- data/app/views/sibu/pages/_map_edit_panel.html.erb +3 -2
- data/app/views/sibu/pages/_media_edit_panel.html.erb +2 -2
- data/app/views/sibu/pages/_new_section_panel.html.erb +1 -1
- data/app/views/sibu/pages/_paragraph_edit_panel.html.erb +2 -2
- data/app/views/sibu/pages/_text_edit_panel.html.erb +2 -2
- data/app/views/sibu/pages/child_element.js.erb +2 -2
- data/app/views/sibu/pages/clone_element.js.erb +2 -2
- data/app/views/sibu/pages/create_section.js.erb +1 -1
- data/app/views/sibu/pages/delete_element.js.erb +1 -1
- data/app/views/sibu/pages/delete_section.js.erb +1 -1
- data/app/views/sibu/pages/edit.html.erb +1 -1
- data/app/views/sibu/pages/edit_element.js.erb +68 -66
- data/app/views/sibu/pages/edit_section.js.erb +6 -5
- data/app/views/sibu/pages/index.html.erb +3 -3
- data/app/views/sibu/pages/new_section.js.erb +22 -13
- data/app/views/sibu/pages/update_element.js.erb +2 -2
- data/app/views/sibu/pages/update_section.js.erb +3 -3
- data/app/views/sibu/sites/index.html.erb +1 -1
- data/db/migrate/20200401130601_add_ref_to_site_templates.rb +5 -0
- data/lib/sibu/engine.rb +0 -2
- data/lib/sibu/version.rb +1 -1
- metadata +3 -18
- data/app/views/sibu/pages/destroy.html.erb +0 -2
- data/app/views/sibu/pages/update.html.erb +0 -2
data/app/models/sibu/page.rb
CHANGED
data/app/models/sibu/site.rb
CHANGED
@@ -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
|
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
|
-
|
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 =
|
58
|
-
editMode.
|
59
|
-
editMode.
|
60
|
-
editMode.
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
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.
|
71
|
-
editMode.
|
72
|
-
editMode.
|
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
|
-
|
75
|
-
|
77
|
+
var topPadding = top <= 120 ? 60 : 120;
|
78
|
+
window.scrollTo(0, top - topPadding);
|
79
|
+
section.classList.add('sb-editing');
|
76
80
|
initInnerOverlays(section);
|
77
|
-
|
81
|
+
document.querySelector("#edit_overlays").innerHTML = "";
|
78
82
|
}
|
79
83
|
|
80
84
|
function cancelEditMode() {
|
81
85
|
refreshAfterEdit(false);
|
82
|
-
|
86
|
+
document.querySelector("#edit_mode_overlay").style.display = "none";
|
83
87
|
cancelEdit();
|
84
|
-
|
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 =
|
93
|
-
var sectionsPanel =
|
94
|
-
sectionsPanel.
|
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
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
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 =
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
section_id: section.
|
118
|
-
entity: section.
|
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 =
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
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
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
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
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
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
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
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
|
-
|
166
|
-
|
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
|
-
|
172
|
-
|
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
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
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.
|
194
|
-
editables.
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
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
|
-
|
236
|
-
var childHeight =
|
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 %>
|