Commit 50a7c7fc authored by Thibaut Frain's avatar Thibaut Frain

Working presentation editor gadget

parent e5044033
......@@ -94,7 +94,9 @@ module.exports = function (grunt) {
"<%= global_config.dest %>/erp5/erp5.css":
"<%= global_config.src %>/erp5/erp5.less",
"<%= global_config.dest %>/twin_erp5/superindex.css":
"<%= global_config.src %>/twin_erp5/superindex.less"
"<%= global_config.src %>/twin_erp5/superindex.less",
"<%= global_config.dest %>/presentation_editor/presentation_editor.css":
"<%= global_config.src %>/presentation_editor/presentation_editor.css"
}
}
},
......@@ -149,6 +151,12 @@ module.exports = function (grunt) {
}
}
},
images: {
expand: true,
cwd: "<%= global_config.src %>/",
src: "**/images/*.*",
dest: "<%= global_config.dest %>/"
},
rsvp: {
src: "node_modules/rsvp/dist/rsvp-2.0.4.min.js",
relative_dest: "lib/rsvp.min.js",
......
......@@ -109,4 +109,67 @@ body {
float: right;
width: 24%;
margin: 3%
}
.ui-panel {
width: 35%;
}
.ui-panel-position-left {
left: -35%;
}
.ui-panel-animate.ui-panel-position-left.ui-panel-display-overlay,
.ui-panel-animate.ui-panel-position-left.ui-panel-display-push {
-webkit-transform: translate3d(-35%,0,0);
-moz-transform: translate3d(-35%,0,0);
transform: translate3d(-35%,0,0);
}
.ui-panel-position-right {
right: -35%;
}
.ui-panel-animate.ui-panel-position-right.ui-panel-display-overlay,
.ui-panel-animate.ui-panel-position-right.ui-panel-display-push {
-webkit-transform: translate3d(35%,0,0);
-moz-transform: translate3d(35%,0,0);
transform: translate3d(35%,0,0);
}
.ui-panel-page-content-position-left,
.ui-panel-dismiss-open.ui-panel-dismiss-position-left {
left: 35%;
right: -35%;
}
.ui-panel-animate.ui-panel-page-content-position-left.ui-panel-page-content-display-reveal,
.ui-panel-animate.ui-panel-page-content-position-left.ui-panel-page-content-display-push {
-webkit-transform: translate3d(35%,0,0);
-moz-transform: translate3d(35%,0,0);
transform: translate3d(35%,0,0);
}
/* panel right open */
.ui-panel-page-content-position-right,
.ui-panel-dismiss-open.ui-panel-dismiss-position-right {
left: -35%;
right: 35%;
}
/* animated: panel right open (for reveal and push) */
.ui-panel-animate.ui-panel-page-content-position-right.ui-panel-page-content-display-reveal,
.ui-panel-animate.ui-panel-page-content-position-right.ui-panel-page-content-display-push {
-webkit-transform: translate3d(-35%,0,0);
-moz-transform: translate3d(-35%,0,0);
transform: translate3d(-35%,0,0);
}
@media (min-width:55em) {
.ui-responsive-panel .ui-panel-page-content-open.ui-panel-page-content-position-left.ui-panel-page-content-display-push,
.ui-responsive-panel .ui-panel-page-content-open.ui-panel-page-content-position-left.ui-panel-page-content-display-reveal {
margin-right: 35%;
}
.ui-responsive-panel .ui-panel-page-content-open.ui-panel-page-content-position-right.ui-panel-page-content-display-push,
.ui-responsive-panel .ui-panel-page-content-open.ui-panel-page-content-position-right.ui-panel-page-content-display-reveal {
margin-left: 35%;
}
}
\ No newline at end of file
......@@ -3,343 +3,355 @@
(function (window, $, html_beautify, rJS) {
"use strict";
var presentation = null,
slideForm,
newSlideButton = $('#add-slide'),
formPanel = $('#form-panel');
formPanel.panel({ beforeclose: function () {
newSlideButton.show("fade");
slideForm.bindToAdd();
}});
function openForm() {
formPanel.panel("open");
newSlideButton.hide("fade");
}
function closeForm() {
formPanel.panel("close");
}
function animate(selector, animation) {
var $selector = $(selector);
$selector.off("animationend webkitAnimationEnd");
$selector.on("animationend webkitAnimationEnd", function () {
$selector.removeClass("animated " + animation);
});
$selector.addClass("animated " + animation);
}
function Slide(params) {
var that = this;
this.html = document.importNode(this.htmlTemplate, true);
this.update(params);
$(this.editBtn()).click(function () {
if (slideForm.currentSlide !== that) {
slideForm.bindToEdit(that);
openForm();
}
});
$(this.deleteBtn()).click(function () {
presentation.deleteSlide(that);
});
}
rJS(window).ready(function (g) {
function readSlide(domElement) {
var $el = $(domElement),
title = $el.find('h1').first().text(),
type = $el.attr('class'),
img,
content = "";
var presentation = null,
slideForm,
newSlideButton = $('#add-slide'),
formPanel = $('#form-panel');
if (type === 'screenshot' || type === 'illustration') {
img = $el.find('img').first().attr('src');
formPanel.panel({ beforeclose: function () {
newSlideButton.show("fade");
slideForm.bindToAdd();
}});
function openForm() {
formPanel.panel("open");
newSlideButton.hide("fade");
}
$el.contents().filter(function () {
return $(this).is(':not(img, h1, details)') || this.nodeType === 3;
}).each(function () {
content += this.outerHTML || this.textContent;
});
function closeForm() {
formPanel.panel("close");
}
return new Slide({
title: title,
type: type,
content: content,
image: img
});
}
Slide.prototype = {
dataTemplate: document.querySelector('template#slide-data')
.content.firstElementChild,
htmlTemplate: document.querySelector('template#slide-html')
.content.firstElementChild,
editBtn: function () {return this.html.querySelector("button.edit"); },
deleteBtn: function () {return this.html.querySelector("button.delete"); },
htmlContent: function () {return this.html.querySelector(".content"); },
htmlImage: function () {return this.html.querySelector("img"); },
htmlTitle: function () {return this.html.querySelector("h1"); },
data: function () {
var res = document.importNode(this.dataTemplate, true), img;
res.className = this.type;
res.querySelector('h1').textContent = this.title;
$(res).append(this.content);
if (this.type === "screenshot" || this.type === "illustration") {
img = document.createElement('img');
img.src = this.image;
res.appendChild(img);
}
return res;
},
update: function (params) {
$.extend(this, params);
this.htmlTitle().textContent = this.title;
this.htmlContent().innerHTML = this.content;
if (this.type === "screenshot" || this.type === "illustration") {
this.htmlImage().src = this.image;
} else {
this.htmlImage().src = "";
}
function animate(selector, animation) {
var $selector = $(selector);
$selector.off("animationend webkitAnimationEnd");
$selector.on("animationend webkitAnimationEnd", function () {
$selector.removeClass("animated " + animation);
});
$selector.addClass("animated " + animation);
}
};
function SlideForm() {
var that = this;
this.elt = document.querySelector("#slide-form");
this.bindToAdd();
$(this.elt).find("#cancel").click(closeForm);
$(this.elt).find('input[type="radio"]').click(function () {
that.updateFieldVisibility(true);
});
$("#image-url").on("change", function () {
that.updatePreview(that.attrImageURL());
});
}
SlideForm.prototype = {
function Slide(params) {
var that = this;
this.html = document.importNode(this.htmlTemplate, true);
this.update(params);
$(this.editBtn()).click(function () {
if (slideForm.currentSlide !== that) {
slideForm.bindToEdit(that);
openForm();
}
});
$(this.deleteBtn()).click(function () {
presentation.deleteSlide(that);
});
}
attrTextInput: function (inputElt, content) {
if (content !== undefined) {
inputElt.value = content;
} else {
return inputElt.value;
}
},
attrTitle: function (content) {
return this.attrTextInput(this.elt.querySelector('#title'), content);
},
attrContent: function (content) {
return this.attrTextInput(this.elt.querySelector('#content'), content);
},
attrDetails: function (content) {
return this.attrTextInput(this.elt.querySelector('#details'), content);
},
attrType: function (type) {
var radios = $(this.elt).find('input[type="radio"]');
if (type !== undefined) {
radios.prop('checked', false);
if (type === "") {type = "basic"; }
radios.filter("#" + type + "-type").prop('checked', true);
radios.checkboxradio('refresh');
this.updateFieldVisibility();
} else {
return radios.filter(':checked').val();
}
},
attrImageURL: function (content) {
return this.attrTextInput(this.elt.querySelector('#image-url'), content);
},
updatePreview: function (content) {
var preview = this.elt.querySelector('#image-preview');
if (content) {
$(preview).show();
preview.src = content;
} else {
$(preview).hide();
}
},
attrAll: function (slide) {
if (slide !== undefined) {
this.attrTitle(slide.title);
this.attrType(slide.type);
this.attrContent(slide.content);
this.attrDetails(slide.details);
this.attrImageURL(slide.image);
this.updatePreview(slide.image);
} else {
return {
title: this.attrTitle(),
type: this.attrType(),
content: this.attrContent(),
details: this.attrDetails(),
image: this.attrImageURL()
};
function readSlide(domElement) {
var $el = $(domElement),
title = $el.find('h1').first().text(),
type = $el.attr('class'),
img,
content = "";
if (type === 'screenshot' || type === 'illustration') {
img = $el.find('img').first().attr('src');
}
},
updateFieldVisibility: function (withEffect) {
var type = this.attrType(),
$imageField = $(this.elt).find('#image-field'),
$imageInputURL = $(this.elt).find('input#image-url');
if (type === "screenshot" || type === "illustration") {
if (withEffect) {
$imageField.show("blind", {direction: "up"});
} else {
$imageField.show();
$el.contents().filter(function () {
return $(this).is(':not(img, h1, details)') || this.nodeType === 3;
}).each(function () {
content += this.outerHTML || this.textContent;
});
return new Slide({
title: title,
type: type,
content: content,
image: img
});
}
Slide.prototype = {
dataTemplate: document
.querySelector('template#slide-data')
.content.firstElementChild,
htmlTemplate: document
.querySelector('template#slide-html')
.content.firstElementChild,
editBtn: function () {
return this.html.querySelector("button.edit");
},
deleteBtn: function () {
return this.html.querySelector("button.delete");
},
htmlContent: function () {
return this.html.querySelector(".content");
},
htmlImage: function () {
return this.html.querySelector("img");
},
htmlTitle: function () {
return this.html.querySelector("h1");
},
data: function () {
var res = document.importNode(this.dataTemplate, true), img;
res.className = this.type;
res.querySelector('h1').textContent = this.title;
$(res).append(this.content);
if (this.type === "screenshot" || this.type === "illustration") {
img = document.createElement('img');
img.src = this.image;
res.appendChild(img);
}
$imageInputURL.attr('required', true);
} else {
if (withEffect) {
$imageField.hide("blind", {direction: "up"});
return res;
},
update: function (params) {
$.extend(this, params);
this.htmlTitle().textContent = this.title;
this.htmlContent().innerHTML = this.content;
if (this.type === "screenshot" || this.type === "illustration") {
this.htmlImage().src = this.image;
} else {
$imageField.hide();
this.htmlImage().src = "";
}
$imageInputURL.attr('required', false);
}
},
setSubmitLabel: function (label) {
var submit = $(this.elt).find("#submit");
submit.prop("value", label).button('refresh');
},
reset: function () {
this.attrAll({title: "",
type: "basic",
content: "",
details: "",
image: ""});
this.currentSlide = null;
$(this.elt).off("submit");
},
bindToEdit: function (slide) {
var that = this;
this.reset();
animate(this.elt, "fadeIn");
that.currentSlide = slide;
this.attrAll(slide);
$(this.elt).submit(function (e) {
slide.update(that.attrAll());
animate(slide.html, "bounce");
e.preventDefault();
that.bindToAdd();
});
this.setSubmitLabel("Save");
},
};
bindToAdd: function () {
function SlideForm() {
var that = this;
this.reset();
$(this.elt).submit(function (e) {
presentation.addSlide(new Slide(that.attrAll()));
that.bindToAdd();
e.preventDefault();
this.elt = document.querySelector("#slide-form");
this.bindToAdd();
$(this.elt).find("#cancel").click(closeForm);
$(this.elt).find('input[type="radio"]').click(function () {
that.updateFieldVisibility(true);
});
$("#image-url").on("change", function () {
that.updatePreview(that.attrImageURL());
});
this.setSubmitLabel("Add");
}
};
function Presentation(DOMElement) {
this.html = DOMElement;
slideForm = new SlideForm();
this.slides = [];
$("#add-slide").click(openForm);
$(this.html).sortable({
update: function (event, ui) {
presentation.updateOrder(ui.item);
}
});
}
Presentation.prototype = {
addSlide: function (slide) {
this.slides.push(slide);
this.html.appendChild(slide.html);
animate(slide.html, "pulse");
return slide;
},
SlideForm.prototype = {
deleteSlide: function (slide) {
if (slideForm.currentSlide === slide) {
slideForm.bindToAdd();
attrTextInput: function (inputElt, content) {
if (content !== undefined) {
inputElt.value = content;
} else {
return inputElt.value;
}
},
attrTitle: function (content) {
return this.attrTextInput(this.elt.querySelector('#title'), content);
},
attrContent: function (content) {
return this.attrTextInput(this.elt.querySelector('#content'), content);
},
attrDetails: function (content) {
return this.attrTextInput(this.elt.querySelector('#details'), content);
},
attrType: function (type) {
var radios = $(this.elt).find('input[type="radio"]');
if (type !== undefined) {
radios.prop('checked', false);
if (type === "") {type = "basic"; }
radios.filter("#" + type + "-type").prop('checked', true);
radios.checkboxradio('refresh');
this.updateFieldVisibility();
} else {
return radios.filter(':checked').val();
}
},
attrImageURL: function (content) {
return this.attrTextInput(this.elt.querySelector('#image-url'),
content);
},
updatePreview: function (content) {
var preview = this.elt.querySelector('#image-preview');
if (content) {
$(preview).show();
preview.src = content;
} else {
$(preview).hide();
}
},
attrAll: function (slide) {
if (slide !== undefined) {
this.attrTitle(slide.title);
this.attrType(slide.type);
this.attrContent(slide.content);
this.attrDetails(slide.details);
this.attrImageURL(slide.image);
this.updatePreview(slide.image);
} else {
return {
title: this.attrTitle(),
type: this.attrType(),
content: this.attrContent(),
details: this.attrDetails(),
image: this.attrImageURL()
};
}
},
updateFieldVisibility: function (withEffect) {
var type = this.attrType(),
$imageField = $(this.elt).find('#image-field'),
$imageInputURL = $(this.elt).find('input#image-url');
if (type === "screenshot" || type === "illustration") {
if (withEffect) {
$imageField.show("blind", {direction: "up"});
} else {
$imageField.show();
}
$imageInputURL.attr('required', true);
} else {
if (withEffect) {
$imageField.hide("blind", {direction: "up"});
} else {
$imageField.hide();
}
$imageInputURL.attr('required', false);
}
},
setSubmitLabel: function (label) {
var submit = $(this.elt).find("#submit");
submit.prop("value", label).button('refresh');
},
reset: function () {
this.attrAll({title: "",
type: "basic",
content: "",
details: "",
image: ""});
this.currentSlide = null;
$(this.elt).off("submit");
},
bindToEdit: function (slide) {
var that = this;
this.reset();
animate(this.elt, "fadeIn");
that.currentSlide = slide;
this.attrAll(slide);
$(this.elt).submit(function (e) {
slide.update(that.attrAll());
animate(slide.html, "bounce");
e.preventDefault();
that.bindToAdd();
});
this.setSubmitLabel("Save");
},
bindToAdd: function () {
var that = this;
this.reset();
$(this.elt).submit(function (e) {
presentation.addSlide(new Slide(that.attrAll()));
that.bindToAdd();
e.preventDefault();
});
this.setSubmitLabel("Add");
}
var index = this.slides.indexOf(slide);
this.slides.splice(index, 1);
animate(slide.html, 'rollOut');
$(slide.html).on("animationend webkitAnimationEnd", function () {
slide.html.remove();
};
function Presentation(DOMElement) {
this.html = DOMElement;
slideForm = new SlideForm();
this.slides = [];
$("#add-slide").click(openForm);
$(this.html).sortable({
update: function (event, ui) {
presentation.updateOrder(ui.item);
}
});
return index;
},
updateOrder: function (DOMElement) {
var newIndex = $(this.html.children).index(DOMElement),
oldIndex,
i,
tmp;
for (i = 0; i < this.slides.length; i += 1) {
if (this.slides[i].html === DOMElement[0]) {
oldIndex = i;
break;
}
Presentation.prototype = {
addSlide: function (slide) {
this.slides.push(slide);
this.html.appendChild(slide.html);
animate(slide.html, "pulse");
return slide;
},
deleteSlide: function (slide) {
if (slideForm.currentSlide === slide) {
slideForm.bindToAdd();
}
var index = this.slides.indexOf(slide);
this.slides.splice(index, 1);
animate(slide.html, 'rollOut');
$(slide.html).on("animationend webkitAnimationEnd", function () {
slide.html.remove();
});
return index;
},
updateOrder: function (DOMElement) {
var newIndex = $(this.html.children).index(DOMElement),
oldIndex,
i,
tmp;
for (i = 0; i < this.slides.length; i += 1) {
if (this.slides[i].html === DOMElement[0]) {
oldIndex = i;
break;
}
}
tmp = this.slides.splice(oldIndex, 1)[0];
this.slides.splice(newIndex, 0, tmp);
},
getContent: function () {
var i, container = document.createElement('div');
for (i = 0; i < this.slides.length; i += 1) {
container.appendChild(this.slides[i].data());
}
return html_beautify(container.innerHTML);
},
setContent: function (content) {
var i, sections, container = document.createElement('div');
container.innerHTML = content;
sections = container.children;
for (i = 0; i < sections.length; i += 1) {
this.addSlide(readSlide(sections[i]));
}
}
tmp = this.slides.splice(oldIndex, 1)[0];
this.slides.splice(newIndex, 0, tmp);
},
getContent: function () {
var i, container = document.createElement('div');
for (i = 0; i < this.slides.length; i += 1) {
container.appendChild(this.slides[i].data());
}
return html_beautify(container.innerHTML);
},
setContent: function (content) {
var i, sections, container = document.createElement('div');
container.innerHTML = content;
sections = container.children;
for (i = 0; i < sections.length; i += 1) {
this.addSlide(readSlide(sections[i]));
}
}
};
};
$.fn.extend({
presentation: function () {
presentation = new Presentation(this[0]);
window.prez = presentation;
return presentation;
}
});
$.fn.extend({
presentation: function () {
presentation = new Presentation(this[0]);
window.prez = presentation;
return presentation;
}
});
rJS(window)
g.editor = $('#slide-list').presentation();
})
.declareMethod('setContent', function (content) {
rJS(this).editor.setContent(content);
this.editor.setContent(content);
})
.declareMethod('getContent', function () {
return rJS(this).editor.getContent();
})
.ready(function (g) {
g.editor = $('#slide-list').presentation();
return this.editor.getContent();
});
}(window, $, html_beautify, rJS));
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment